Co dzieje się, gdy czytasz plik, gdy jest on nadpisany?

Odpowiedzi:

19

To zależy od tego, co robi pisarz.

Jeśli program piszący zastąpi istniejący plik, czytelnik zobaczy nową treść, gdy program piszący przejmie czytnik, jeśli w ogóle. Jeśli pisarz i czytelnik działają ze zmienną prędkością, czytelnik może naprzemiennie wyświetlać starą i nową treść.

Jeśli program piszący przycina plik, zanim zacznie zapisywać, czytnik uruchomi się na końcu pliku w tym momencie.

Jeśli program piszący utworzy nowy plik, a następnie przeniesie nowy plik do starej nazwy, czytnik będzie kontynuował czytanie ze starego pliku. Jeśli otwarty plik zostanie przeniesiony lub usunięty, procesy, które go otworzyły, kontynuują czytanie z tego samego pliku. Jeśli plik zostanie usunięty, faktycznie pozostaje na dysku (ale nie ma możliwości jego ponownego otwarcia), dopóki ostatni proces go nie zamknie.

Systemy uniksowe zwykle nie mają obowiązkowych blokad . Jeśli aplikacja chce się upewnić, że komponent piszący i komponent czytający nie nadepną na siebie, programista musi zastosować odpowiednie blokowanie. Istnieje kilka wyjątków, w których plik otwarty przez jądro może być chroniony przed zapisem przez aplikacje użytkownika, na przykład obraz systemu plików w pętli lub plik wykonywalny wykonywany w niektórych wariantach unixa.

Gilles „SO- przestań być zły”
źródło
Gilles, czy twoje wyjaśnienia dotyczą także scenariuszy ftp/ sftpPowiedzmy, że proces rozpoczyna odczyt przesłanego ftppliku, gdy inna wersja tego samego pliku zastępuje go z powodu nowej transmisji.
iruvar
@ 1_CR Tak. W takim przypadku pisarz i czytnik są procesami ftpd.
Gilles 'SO - przestań być zły'
jakie jest znaczenie wyprzedzania tutaj?
Victor Choy,
@VictorChoy Standardowe znaczenie: zaczynać za / za kimś innym i w pewnym momencie iść przed nim.
Gilles „SO- przestań być zły”
18

Jest to klasyczny warunek wyścigu, więc wynik jest z definicji nieprzewidywalny.

Między innymi zależy to od

  • fopen(3)lub open(2)tryby zapisu,
  • jak / jeśli pisarz buforuje dane wyjściowe,
  • jak czytnik czyta plik,
  • różnica prędkości między czytnikiem a pisarzem,
  • różnica czasu między początkiem czytania a pisaniem.
  • I oczywiście w nowoczesnych maszynach wielordzeniowych sprawy komplikują jeszcze bardziej inne czynniki niżej (np. Harmonogramowanie procesów).

Jeśli musisz być w stanie odczytać plik podczas jego przepisywania, możesz zmusić program piszący do utworzenia przejściowej kopii pliku, zmodyfikować go, a następnie skopiować z powrotem do oryginalnego pliku. Tak to rsyncrobi na przykład. Istnieje wiele sposobów realizacji tego, ale nie ma darmowego lunchu. Każda metoda ma swoje własne wady i konsekwencje.

Alexios
źródło
1
Ta odpowiedź jest o wiele bardziej wyczerpująca niż moja. Usuwanie mojej odpowiedzi
killermist
0

Poprzedni respondenci mieli bardziej wyczerpujące wyjaśnienia niż to, ale oto sztuczka, która na pewno działa również, robiąc dokładnie to, czego chce:

$ tail -f <filename>

Pokaże koniec pliku podczas jego zapisywania. Przydaje się, jeśli chcesz potokować STDERR do pliku, ale nadal widzisz go na przykład w innym oknie terminala.

Willoughby Will
źródło