czy w Pythonie istnieje analog COMMIT do zapisu do pliku?

Mam plik otwarty do zapisu, a proces trwa kilka dni — coś jest zapisywane w pliku w stosunkowo przypadkowych momentach. Rozumiem, że dopóki nie wykonam file.close() istnieje ryzyko, że tak naprawdę nic nie zostanie zapisane na dysku. Czy to prawda?

Co się stanie, jeśli system ulegnie awarii, gdy główny proces nie zostanie jeszcze ukończony? Czy istnieje sposób na dokonanie zatwierdzenia raz na... powiedzmy - 10 minut (sam nazywam to zatwierdzeniem - nie ma potrzeby uruchamiania timera)? Czy file.close() i open(file,'a') to jedyny sposób, czy też istnieją lepsze alternatywy?


person user63503    schedule 03.03.2009    source źródło


Odpowiedzi (4)


Powinieneś być w stanie użyć file.flush(), aby to zrobić.

person zweiterlinde    schedule 03.03.2009
comment
A jeśli chcesz powiedzieć systemowi operacyjnemu, aby natychmiast zapisał go na dysk (zamiast potencjalnie pozostać w buforach systemu operacyjnego i zgubić się w przypadku nagłej awarii zasilania), dodaj os.fsync(file.fileno()) po flush; flush opróżnia bufory trybu użytkownika Pythona, fsync opróżnia bufory trybu jądra systemu operacyjnego (i często sugeruje podstawowemu sprzętowi dyskowemu, że faktycznie zapisuje to natychmiast, chociaż wiele dysków leży, więc może pozostać przez jakiś czas w buforach dysku) . - person ShadowRanger; 14.10.2020

Jeśli nie chcesz przerywać bieżącego procesu w celu dodania f.flush() (wygląda na to, że działa już od kilku dni?), wszystko powinno być w porządku. Jeśli zauważysz, że plik, do którego piszesz, staje się coraz większy, nie stracisz tych danych...

Z dokumentów Pythona:

write(str) Zapisz ciąg znaków do pliku. Nie ma wartości zwracanej. Ze względu na buforowanie ciąg znaków może nie pojawić się w pliku do czasu wywołania metody Flush() lub Close().

Wygląda na to, że system buforowania Pythona automatycznie opróżnia obiekty plików, ale nie ma gwarancji, że tak się stanie.

person Jason Coon    schedule 03.03.2009

Aby mieć pewność, że dane zostaną zapisane na dysku, użyj file.flush(), a następnie os.fsync(file.fileno()).

person Benjamin Peterson    schedule 03.03.2009

Jak już powiedziano, użyj metody .flush(), aby wymusić zapis z bufora, ale unikaj używania wielu wywołań do opróżniania, ponieważ może to w rzeczywistości spowolnić zapis (jeśli aplikacja opiera się na szybkich zapisach) podczas zmuszę twój system plików do zapisania zmian mniejszych niż rozmiar bufora, co może rzucić cię na kolana. :)

person Christian Witts    schedule 04.03.2009