2013-06-12 14 views
7

Python'da büyük bir dosya okurken bu yöntemlerin RAM kullanımındaki farkı anlamak isterim.Parçalar içinde dosya oku - RAM kullanımı, ikili dosyalardaki dizeleri oku

f = open(file, 'rb') 
while True: 
    piece = f.read(1024)  
    process_data(piece)   
f.close() 

dosya her iki versiyonda da kısmen okunur: stackoverflow burada bulunan

Versiyon 1, i Yukarıdaki kod bulmadan önce

def read_in_chunks(file_object, chunk_size=1024): 
    while True: 
     data = file_object.read(chunk_size) 
     if not data: 
      break 
     yield data 


f = open(file, 'rb') 
for piece in read_in_chunks(f): 
    process_data(piece)   
f.close() 

Sürüm 2, i kullandı. Ve mevcut parça işlenebilir. İkinci örnekte, piece her döngüde yeni içerik alıyor, bu yüzden bu işi belleğe tamamlanmış bir dosyaya yükleyemezsiniz diye düşündüm ..?

Ama gerçekten yield'un ne yaptığını anlamıyorum ve eminim ki burada yanlış bir şey var. Bunu bana açıklayan var mı?


kullanılan yöntemin yanı sıra, Kafamı kurcalayan başka bir şey yoktur: Yukarıdaki örneklerde

okuduğum parçasının içeriği yığın-boyutuna göre tanımlanır, 1KB. Ama ... eğer dosyada dizeleri aramam gerekirse? "ThisIsTheStringILikeToFind" gibi bir şey?

Dize dosyasında nerede bulunduğuna bağlı olarak, bir parça "ThisIsTheStr" parçasını içerir - ve sonraki parça "ingILikeToFind" içerir. Böyle bir yöntem kullanarak, bütün dizeyi herhangi bir parçada tespit etmek mümkün değildir.

Parçalar halinde bir dosyayı okumak için bir yol var - ama bir şekilde böyle dizeleri önemsiyor musunuz?

Herhangi bir yardım veya fikri açığız,

greets!

+0

Eğer ilk parçasını yazabiliriz '("" b kısmi (f.read, parça_boyutu)) ITER olarak parça için : process_data (yığın) '(ikili modunu varsayar). Son soruya verilen cevap evet: sadece öbek dizgisinin önekleriyle bitip bitmeyeceğini ve sonraki parçanın ilgili sonekle başlayıp başlamadığını kontrol et. – jfs

+0

"iter" i belirtdiğiniz için teşekkür ederiz - bunu bilmiyordum! İkinci soru hakkında: “T” veya “Th” veya “Thi” veya “Bu” ile biten parçanın bitip bitmediğini kontrol edebilir miyim? Hmm, iyi fikir! Teşekkürler! – xph

cevap

15

yield, üretici ifadeleri için kullanılan python anahtar sözcüktür. Bu, fonksiyonun bir sonraki çağrıldığında (veya tekrarlandığında), yürütmenin, son aradığınız zaman bıraktığı tam noktada başlayacağı anlamına gelir. İki fonksiyon aynı şekilde çalışır; Tek fark, birincinin ikincisinden biraz daha fazla çağrı yığını alanı kullanmasıdır. Ancak, birincisi çok daha fazla yeniden kullanılabilir, bu yüzden bir program tasarım açısından, birincisi aslında daha iyi.

DÜZENLEME: Ayrıca, bir diğer fark ilki okundu kez tüm verileri okuma gerektiği şekilde durdurur, ancak ikincisi sadece bir kez f.read() veya process_data() ya bir istisna atar durur olmasıdır. düzgün bir şekilde ikinci bir çalışma sahip olmak için, bu kadar gibi değiştirin gerekir:

f = open(file, 'rb') 
while True: 
    piece = f.read(1024) 
    if not piece: 
     break 
    process_data(piece) 
f.close() 
+0

Cevabınız için teşekkürler! İlk versiyonun yeniden kullanılabilir olduğunu, diğer projelerde de faydalı olabilecek bir işlevi tanımladığını anlıyorum. Büyük "çağrı yığını alanı" bunun sonucu, sanırım? Bir fonksiyon yaratmak mı?Ancak dosyanın RAM kullanımında bir fark yok mu? Jeneratör işlevleri hakkında bazı belgeler buldum, her zaman ortak fonksiyonlar olduğunda anlamanız kolay değil - ama bu hakkı elde ettiysem, ilk versiyon sadece dosyanın ilk parçasını 'geri döndürecek' ve 'for'-loop' verim 'olmadan' parça 'verisinden geçebilir mi? – xph

+0

Cevabımı sevdiyseniz, kabul edilen cevap olarak işaretleyebilir misiniz? (aslında bunu yapmak için 2 rep alırsınız) – AJMansfield

+0

Oh, evet! Tabii ki üzgünüm ... – xph