2011-02-01 8 views
8

Czy w takim przypadku jest zwyczaj otwierać plik tylko raz?Czy powinienem zachować plik otwarty, czy powinienem często otwierać i zamykać?

#!/usr/bin/env perl 
use warnings; 
use 5.012; 
use autodie; 

my $file = 'my_file'; 

open my $fh, '>>', $file; 
say $fh "Begin"; 
close $fh; 

$SIG{INT} = sub { 
    open my $fh, '>>', $file; 
    say $fh "End"; 
    close $fh; 
    exit 
}; 

my $result; 
while (1) { 
    $result++; 
    # ... 
    # ... 
    # ... 
    open my $fh, '>>', $file; 
    say $fh $result; 
    close $fh; 
    sleep 3; 
} 

Odpowiedz

20

Krótka odpowiedź: tylko raz Prawie zawsze, należy otworzyć/zamknąć . Szczegóły poniżej.

Decyzja czy robić to zależy od 4 rzeczy:

  1. istnieją inne procesy, które mogą wymagać zapisu pliku?

    Jeśli tak, może być konieczne zablokowanie pliku, a dobrym zachowaniem dla procesu przeznaczonego do współbieżnego użycia jest zwolnienie zablokowanego udostępnionego zasobu tak szybko, jak to możliwe, aby inni mogli uzyskać blokadę.

  2. Czy istnieje wiele plików, które należy otworzyć?

    Jeśli tak, może zabraknąć uchwytów plików ze zbyt dużą liczbą otwartych plików, więc musisz zamknąć.

  3. Ile tolerancji masz na utratę danych w pliku, jeśli program ulega awarii.

    Jeśli chcesz zapisać dane z bufora do pliku, musisz je wyczyścić. Można to zrobić przez częste zamykanie, chociaż lepszym rozwiązaniem jest częste płukanie lub automatyczne włączanie uchwytu pliku.

  4. Czy bardzo zależy Ci na tym, aby nie można było zamknąć pliku po wyczerpaniu miejsca na dysku?

    Jeśli tak, to im częściej zamkniesz/otworzysz ponownie plik, tym mniej danych stracisz z powodu pełnego zapełnienia systemu plików, więc wszystko, co napisałeś od ostatniego open, zniknęło.

W każdym innym scenariuszu, tylko otwieranie/zamykanie raz (dobrze, plus może dodatkowo blisko w __DIE__ obsługi i END{} bloku (i większość czasu, to prawdopodobnie w innych sytuacjach).

To dlatego, że otwieranie/zamykanie pliku powoduje marnowanie zasobów systemowych bez żadnego powodu ORAZ powoduje wydłużenie czasu twojego kodu. Bardziej szczegółowo, otwieranie i zamykanie pliku jest kosztowną operacją, wymagającą zarówno wywołań systemowych (które mogą wymusić przeskok do jądra z poziomu użytkownika) i dodatkowe dyskowe IO, które są BARDZO drogie pod względem zasobów. Aby to sprawdzić, uruchom narzędzie do mierzenia wykorzystania systemu na swoim O S i uruchom skrypt Perla, który nie robi nic oprócz otwierania/zamykania 10000 różnych nazw plików po 100 razy.

Uwaga (w odniesieniu do scenariuszy nr 3/# 4), że jeśli bardzo zależy Ci na tym, aby nie utracić danych, nie powinieneś używać pliku IO na pierwszym miejscu - użyj bazy danych lub systemu wiadomości z gwarancjami dostawy .

+0

Co więcej, na ile chcesz się napić podczas otwierania i zamykania - nie są to operacje bezpłatne. –

+0

Zastanowiłem się nad uwzględnieniem kwestii współbieżności i blokowania w mojej odpowiedzi, ale uznałem, że było to zbyt odbiegające od jego pytania. Jednak możliwe jest, że łączy się on z zamknięciem i zalaniem. Ponieważ prawidłowo wskazuje się na obsługę spójności danych w obliczu możliwego współbieżnego dostępu, należy użyć blokowania, a w celu zminimalizowania rywalizacji o blokadę i ryzyka niespójności pliku/bufora należy wyraźnie opróżnić po operacji zapisu. –

+0

@ S.Lott - to jest pod ogólnym nagłówkiem "odpadów zasobów systemowych", ale trochę się rozwiną :) – DVK

4

Przy zwyczajnym programowaniu jest zwyczaj otwierania każdego pliku i utrzymywania uchwytu otwartego pliku tak długo, jak długo przetwarzanie będzie dla niego użyteczne.

Wyjątkiem byłaby obsługa pliku ograniczona do określonych części kodu (na przykład inicjalizacja i wyłączenie) lub do określonych i stosunkowo rzadkich zdarzeń (procedura obsługi sygnału związana z ponownym odczytaniem konfiguracji lub aktualizacją statystyczną lub debugowanie zrzutów).

W tym przykładzie pokazano, że dodatkowe operacje otwierania i zamykania są całkowicie zbędne (i prawdopodobnie kosztowne pod względem wydajności i obciążenia systemu).

Powiązane problemy