2009-09-16 7 views
6

Pod warunkiem, że wiemy, że cały plik zostanie załadowany do pamięci i możemy sobie na to pozwolić, jakie są wady (jeśli występują) lub ograniczenia (jeśli występują) ładowania całego pliku (ewentualnie pliku binarnego) w pythonie zmienna. Jeśli jest to technicznie możliwe, czy należy tego unikać i dlaczego?Czy możemy użyć zmiennej Pythona do przechowywania całego pliku?

Odnośnie do wielkości pliku, do jakiego maksymalnego rozmiaru należy ograniczyć to rozwiązanie? I dlaczego ?

Rzeczywistym kodem ładowania może być kod proponowany w this stackoverflow entry.

Przykładowy kod jest:

def file_get_contents(filename): 
    with open(filename) as f: 
     return f.read() 

content = file_get_contents('/bin/kill') 

... code manipulating 'content' ... 

[EDIT] manipulacja Kod, który przychodzi do głowy (ale nie jest to być może ma to zastosowanie) jest standardową listę/strings operatorzy (nawiasy kwadratowe, '+' znaki) lub sznurek operatorzy ("len", "in" operator, "count", "endswith"/"startswith", "split", "tłumaczenie" ...).

Odpowiedz

6

Podczas gdy otrzymałeś dobre odpowiedzi, wydaje się, że nikt nie odpowiedział na tę część twojego pytania (jak to często bywa, gdy zadajesz wiele pytań w pytaniu ;-) ...:

Jeśli chodzi o obawy rozmiar pliku, aby co maksymalny rozmiar to rozwiązanie powinno być ograniczone?. I dlaczego ?

Najważniejszą rzeczą jest to, ile pamięci RAM może to specyficzny proces Python rzeczywiście użycie (co jest znane jako „zestaw roboczy”), bez nadmiernego obciążania innych aspektów wydajności całego systemu jest. Jeśli przekroczysz fizyczną pamięć RAM dla swojego "zestawu roboczego", będziesz paginować i wymieniać się na dysk, a twoja wydajność może szybko ulec pogorszeniu (aż do stanu znanego jako "rzucanie", w zasadzie wszystkie dostępne cykle idą do zadania związane z przenoszeniem i wyjmowaniem stron oraz niewielkimi ilościami rzeczywistej pracy mogą zostać wykonane).

Spośród tej sumy, rozsądnie skromna kwota (powiedzmy kilka MB co do zasady, ogólnie) prawdopodobnie zostanie pobrana przez kod wykonywalny (własne pliki wykonywalne Pythona, biblioteki DLL lub .so) oraz kod bajtowy i ogólne wsparcie bazy danych, które są aktywnie potrzebne w pamięci; na typowej nowoczesnej maszynie, która nie wykonuje innych ważnych lub pilnych zadań, możesz prawie zignorować ten narzut w porównaniu do gigabajtów pamięci RAM, które masz ogólnie dostępne (chociaż sytuacja może być inna w systemach wbudowanych, itp.).

Cała reszta jest dostępna dla twoich danych - w tym ten plik, który czytasz do pamięci, a także inne istotne struktury danych. "Modyfikacje" danych pliku zazwyczaj zajmują (przejściowo) dwukrotnie więcej pamięci niż rozmiar zawartości pliku (jeśli trzymasz go w ciągu znaków) - więcej, oczywiście, jeśli przechowujesz kopię stare dane, a także tworzenie nowych zmodyfikowanych kopii/wersji.

Tak więc dla "tylko do odczytu" użyj na typowej nowoczesnej maszynie 32-bitowej z, powiedzmy, 2 GB pamięci RAM ogólnie, odczytywanie do pamięci (powiedzmy) 1,5 GB nie powinno być problemem; ale musi to być znacznie mniej niż 1 GB, jeśli robisz "modyfikacje" (a nawet mniej, jeśli masz inne istotne struktury danych w pamięci!). Oczywiście na dedykowanym serwerze z 64-bitową kompilacją Pythona, 64-bitowym systemem operacyjnym i 16 GB pamięci RAM, praktyczne ograniczenia przed bardzo różnymi - w przybliżeniu proporcjonalnie do znacznie różnej ilości dostępnej pamięci RAM.

Na przykład, tekst Biblii Króla Jakuba dostępny do pobrania here (rozpakowany) to około 4,4 MB; więc w maszynie z 2 GB pamięci RAM można zachować około 400 nieznacznie zmodyfikowanych kopii w pamięci (jeśli nic innego nie wymaga pamięci), ale na komputerze z 16 (dostępnym i adresowalnym) GB pamięci RAM można zachowaj ponad 3000 takich kopii.

11
  • Tak, można
  • Jedyną wadą jest wykorzystanie pamięci i możliwe również przyspieszyć, jeśli plik jest duży.
  • Rozmiar pliku powinien być ograniczony do ilości dostępnego miejsca w pamięci.

Ogólnie rzecz biorąc, istnieją lepsze sposoby, aby to zrobić, ale dla jednorazowych skryptów, w których pamięć nie jest problemem, na pewno.

3

Jedyny problem, jaki można napotkać, to zużycie pamięci: ciągi znaków w języku Python są niezmienne. Więc kiedy trzeba zmienić bajt, trzeba skopiować stary napis:

new = old[0:pos] + newByte + old[pos+1:] 

To musi się do trzykrotnej pamięci old.

Zamiast napisu możesz użyć numeru array. Oferują one znacznie lepszą wydajność, jeśli trzeba zmodyfikować zawartość i można je łatwo utworzyć z ciągu.

4
with open(filename) as f: 

Działa to tylko na Pythonie 2.x na systemie Unix. Nie zrobi tego, czego się spodziewasz w Pythonie 3.x lub Windowsie, ponieważ oba te rysują silne rozróżnienie pomiędzy tekstem a plikami binarnymi. Lepiej określić, czy plik jest binarny, tak:

with open(filename, 'rb') as f: 

To wyłączy konwersji CR/LF OS w systemie Windows, a zmusi Pythona 3.x zwraca tablicę bajtów zamiast znaków Unicode.

Co do pozostałej części pytania, zgadzam się z odpowiedzią Lennart Regebro (nieedytowaną).

0

Tak, można zapewnić, że plik jest wystarczająco mały-.

Jest nawet bardzo pythonic, aby dalej konwertować powrót z read() do dowolnego typu kontenera/iteracji, jak powiedzmy, string.split(), wraz z towarzyszącymi funkcjami programowania funkcjonalnego, aby kontynuować traktowanie pliku "od razu".

1

Można również użyć funkcji Pythona v3:

>>> ''.join(open('htdocs/config.php', 'r').readlines()) 
"This is the first line of the file.\nSecond line of the file" 

Czytaj więcej http://docs.python.org/py3k/tutorial/inputoutput.html

+1

Zobacz moje inne komentarz, spamowanie stare posty z duplikatów odpowiedzi nie jest konstruktywne. – Kev

Powiązane problemy