Zazwyczaj występują dwa poziomy buforowania:
- Bufory wewnętrzne
- Bufory systemu operacyjnego
Bufory wewnętrzne to bufory utworzone przez środowisko wykonawcze / bibliotekę / język, w odniesieniu do których programujesz, i mają na celu przyspieszenie działania poprzez unikanie wywołań systemowych przy każdym zapisie. Zamiast tego, kiedy piszesz do obiektu pliku, zapisujesz do jego bufora, a gdy bufor się zapełnia, dane są zapisywane do właściwego pliku za pomocą wywołań systemowych.
Jednak ze względu na bufory systemu operacyjnego może to nie oznaczać, że dane są zapisywane na dysku . Może to po prostu oznaczać, że dane są kopiowane z buforów utrzymywanych przez środowisko wykonawcze do buforów obsługiwanych przez system operacyjny.
Jeśli coś napiszesz i skończy się to w buforze (tylko), a zasilanie zostanie odcięte, dane nie będą znajdować się na dysku, gdy maszyna się wyłączy.
Tak, aby pomóc z tym masz flush
i fsync
metod, na swoich obiektach.
Pierwszy, flush
po prostu zapisze wszelkie dane, które pozostają w buforze programu, do właściwego pliku. Zwykle oznacza to, że dane zostaną skopiowane z bufora programu do bufora systemu operacyjnego.
W szczególności oznacza to, że jeśli inny proces ma ten sam plik otwarty do odczytu, będzie mógł uzyskać dostęp do danych, które właśnie przesłałeś do pliku. Jednak nie musi to oznaczać, że został on „trwale” zapisany na dysku.
Aby to zrobić, musisz wywołać os.fsync
metodę, która zapewnia, że wszystkie bufory systemu operacyjnego są zsynchronizowane z urządzeniami pamięci masowej, dla których są przeznaczone, innymi słowy, ta metoda skopiuje dane z buforów systemu operacyjnego na dysk.
Zazwyczaj nie musisz zawracać sobie głowy żadną metodą, ale jeśli jesteś w scenariuszu, w którym paranoja dotycząca tego, co faktycznie trafia na dysk, jest dobrą rzeczą, powinieneś wykonać oba połączenia zgodnie z instrukcją.
Uzupełnienie w 2018 r.
Zauważ, że dyski z mechanizmami pamięci podręcznej są teraz znacznie bardziej powszechne niż w 2013 roku, więc teraz jest zaangażowanych jeszcze więcej poziomów buforowania i buforów. Zakładam , że te bufory będą również obsługiwane przez wywołania sync / flush, ale tak naprawdę nie wiem.
with file('blah') as fd: #dostuff
konstrukcji, wiem, że gwarantuje ona zamknięcie deskryptora pliku. Czy również opróżnia lub synchronizuje?fsync
jest niezbędna dla atomowości. nie możesz oczekiwać, że zamkniesz plik, otworzysz go ponownie i znajdziesz zawartość bezfsync
pośrodku. Często działa, ale nie działa na Linuksie z na przykład ext4 i domyślnymi opcjami montowania. Niefsync
ma również gwarancji, że naprawdę magnetycznie odwrócisz żelazko na talerzach, ponieważ 1: fsync można wyłączyć (w trybie laptopa), a 2: wewnętrzne buforowanie dysku twardego może nie zostać poinstruowane, aby opróżnić.Ponieważ system operacyjny może tego nie robić. Operacja opróżniania wymusza zapisanie danych pliku do pamięci podręcznej plików w pamięci RAM, a stamtąd zadaniem systemu operacyjnego jest wysłanie ich na dysk.
źródło
actually
jest to względne: jeśli urządzenie docelowe ma włączone buforowanie zapisu, dane mogą nie osiągnąć rzeczywistych talerzy / chipów poos.fsync()
powrocie.Opróżnia bufor wewnętrzny, co ma spowodować, że system operacyjny wypisze bufor do pliku. [1] Python używa domyślnego buforowania systemu operacyjnego, chyba że skonfigurujesz go inaczej.
Ale czasami system operacyjny nadal nie chce współpracować. Zwłaszcza w przypadku wspaniałych rzeczy, takich jak opóźnienia zapisu w systemie Windows / NTFS. Zasadniczo bufor wewnętrzny jest opróżniany, ale bufor systemu operacyjnego nadal go utrzymuje. Musisz więc powiedzieć systemowi operacyjnemu, aby zapisał go na dysku
os.fsync()
w takich przypadkach.[1] http://docs.python.org/library/stdtypes.html
źródło
Zasadniczo flush () czyści bufor pamięci RAM, jego prawdziwą mocą jest to, że umożliwia dalsze zapisywanie w nim później - ale nie należy go uważać za najlepszą / najbezpieczniejszą funkcję zapisu do pliku. To opróżnianie pamięci RAM, aby uzyskać więcej danych, to wszystko. Jeśli chcesz mieć pewność, że dane zostaną bezpiecznie zapisane do pliku, użyj zamiast tego close ().
źródło