2010-02-10 13 views
7

W następnym Pythonie:Czy funkcja "open" w Pythonie zachowuje jej zawartość w pamięci lub w pliku tymczasowym?

fp = open('output.txt', 'wb') 
# Very big file, writes a lot of lines, n is a very large number 
for i in range(1, n): 
    fp.write('something' * n) 
fp.close() 

procesowych zapisu powyżej może trwać dłużej niż 30 minut. Czasami pojawia się błąd MemoryError. Czy zawartość pliku przed zamknięciem jest przechowywana w pamięci lub zapisana w pliku tymczasowym? Jeśli znajduje się w pliku tymczasowym, jaka jest jego ogólna lokalizacja w systemie Linux?

Edit:

Dodany fp.write w pętli for

+0

Czy faktycznie wydajesz wiele połączeń do 'fp.write', czy zbierasz je wszystkie w jednym dużym ciągu i wypisujesz jednocześnie? To drugie byłoby raczej nieefektywne. –

+0

To wywołanie wielokrotnego zapisu w pętli for. –

+0

pokaż kod. jeśli napiszesz wiersz o jedną linię za linię, nie powinno to stanowić problemu. – ghostdog74

Odpowiedz

5

on przechowywany w pamięci podręcznej dysku systemu operacyjnego w pamięci, dopóki nie jest opróżniany na dysku, albo pośrednio z powodu problemów czasowych czy kosmicznych, lub jawnie przez fp.flush().

+2

Po skorygowaniu pytania stało się jasne, że '' coś' * spowoduje poważne problemy z pamięcią, gdy 'n' stanie się duży. Zapisywanie plików nie ma nic wspólnego z '' coś' * wyczerpującą pamięcią n. –

3

Będzie buforowanie zapisu w jądrze systemu Linux, ale w (i) regularnych odstępach czasu będą one przepłukiwane na dysk. Utrata takiej przestrzeni buforowej nigdy nie powinna powodować błędu pamięci na poziomie aplikacji; bufory powinny opróżnić się zanim to nastąpi, wstrzymując aplikację w tym czasie.

1

Jeśli piszesz duży plik, którego zapisy mogą zawieść, lepiej spłucz plik na dysk w regularnych odstępach czasu, używając fp.flush(). Dzięki temu plik będzie w miejscu swojego wyboru, że można łatwo dostać się zamiast być na łasce OS:

fp = open('output.txt', 'wb') 
counter = 0 
for line in many_lines: 
    file.write(line) 
    counter += 1 
    if counter > 999: 
     fp.flush() 
fp.close() 

to będzie opróżnić pliku na dysk co 1000 wierszy.

0

Jeśli piszesz wiersz po linii, nie powinno to stanowić problemu. Powinieneś pokazać kod tego, co robisz przed napisaniem. Na początek możesz spróbować usunąć obiekty, które nie są konieczne, użyj fp.flush() itd.

0

Zapisywanie pliku nigdy nie powinno powodować błędu pamięci; z dużym prawdopodobieństwem masz błąd w innym miejscu.

Jeśli masz pętlę i błąd pamięci, to powinienem sprawdzić, czy są "przeciekające" odniesienia do obiektów.
Coś jak:

def do_something(a, b = []): 
    b.append(a) 
    return b 

fp = open('output.txt', 'wb') 

for i in range(1, n): 
    something = do_something(i) 
    fp.write(something) 

fp.close() 

Jestem teraz zbierając tylko przykład, ale w konkretnym przypadku wycieku odniesienia może być znacznie trudniejsze do znalezienia; jednak ten przypadek po prostu wycieknie pamięci wewnątrz do_something ze względu na sposób, w jaki Python obsługuje domyślne parametry funkcji.

2

Opierając się na komentarzu ataylor do pytania:

Może chcesz zagnieździć swoją pętlę. Coś jak

for i in range(1,n): 
    for each in range n: 
     fp.write('something') 
fp.close() 

ten sposób, jedyną rzeczą, która zostaje wprowadzony do pamięci jest ciąg "something" nie "something" * n.

+0

+1: Tworzenie '" czegoś "* n' dla dużych wartości' n' spowoduje wyczerpanie pamięci. Zapisywanie do pliku zajmuje bardzo mało pamięci. –

Powiązane problemy