2012-04-19 17 views
15

Ben ancak bazen piton bir seferde 2 hatlarında okuyup sıralamak olacak, bir 20Gb dosyasını ayrıştırma ve başka bir dosyaya belirli bir koşulu karşılayan hattının çıkışını ediyorum olarak 2 hatlarında okuma onlar.Ayrıştırma büyük (20GB) metin dosyası - 1

inputFileHandle = open(inputFileName, 'r') 

row = 0 

for line in inputFileHandle: 
    row = row + 1 
    if line_meets_condition: 
     outputFileHandle.write(line) 
    else: 
     lstIgnoredRows.append(row) 

Ben kaynak dosyada satır sonlarını kontrol ettim ve hat (ASCII char, 10) besleyen onlar kontrol edin. Problem satırlarını dışarıya çekerek ve izolasyon çalışmalarını beklendiği gibi ayrıştırmak. Burada bir python sınırlaması var mı? İlk anomali dosyasındaki pozisyon 4GB işareti civarındadır.

+0

yumruk anomali hep saymak aynı çizgide tutarlı meydana gelir? Ayrıca, lstIgnoredRows bir liste, ne kadar büyüyor? Çıktı dosyasına ilgi duyduğunuz satırları kurtardıysanız ve göz ardı etmek istediğiniz satırlarla hiçbir şey yapmadıysanız ne olacağını merak ediyorum. – Levon

+1

Belki de bu soruya benzer, tembel bir yöntem kullanarak dosyanın daha küçük parçalarını okumayı deneyebilirsiniz? Bir atış verin http://stackoverflow.com/questions/519633/lazy-method-for-reading-big-file-in-python – prrao

+0

Her seferinde aynı satırda olur. lstIgnoredRows birkaç bin ürüne kadar büyüyebilir. – James

cevap

23

Hızlı google arama çok çok sonuçlar vermiştir: Bu numaralandırmak kullanılırsa

FWIW, pasajı biraz daha temiz olacaktır. Bakınız here for such an exampleand another one which takes over from the first.

Python ile bir sinek. Şimdi

, böcek açıklaması; Çoğaltması kolay değildir, çünkü hem iç FILE arabellek boyutuna hem de fread'e iletilen karakterlerin sayısına() bağlıdır. Microsoft CRT kaynak kodunda, open.c'de bu teşvik edici yorumla başlayan bir blok var. "Bu zor kısım. Tamponun sonunda bir CR bulduk. Bir sonraki char bir LF olup olmadığını görmek için göz atmalıyız. ." Tuhaf olarak, bu işlevin hemen hemen tam bir kopyası, kaynak kodunda: http://perl5.git.perl.org/perl.git/blob/4342f4d6df6a7dfa22a470aa21e54a5622c009f3:/win32/win32.c#l3668 Sorun, aramadan sonra bir konum geri adım atmak için kullanılan SetFilePointer() çağrısıdır; 32bit DWORD'de geçerli konumu döndüremediği için başarısız olur. [Düzeltme kolaydır; Bunu görüyor musunuz?] Bu noktada, işlev sonraki read() öğesinin LF'yi döndüreceğini düşünür, ancak dosya tanıtıcısı geri taşınmadığından dolayı olmaz.

Ve-etrafında çalışma:

Ama bu Python 3.x not (ham dosyaları her zaman ikili modda açılır ve CRLF çeviri Python tarafından yapılır) etkilenmez; 2.7 ile io.open() kullanabilirsiniz.

+1

Dosyayı ikili modda açma bu sorunu giderdi. yardımınız için teşekkürler (inputFileName, 'rb') – James

+0

ikili modda açarak benim için de çözdüm, bu bir hayat kurtarıcı! – tlamadon

7

4GB işareti garip bir şekilde 32 bit kaydedicisine (** 32 2) saklanabilir maksimum değerin yakındır.

Yayınladığınız kod kendisi tarafından gayet iyi görünüyor, bu yüzden Python yapı bir hata şüpheli olur. "4GB daha büyük piton okuma dosyalar" için

inputFileHandle = open(inputFileName, 'r') 

for row, line in enumerate(inputFileHandle): 
    if line_meets_condition: 
     outputFileHandle.write(line) 
    else: 
     lstIgnoredRows.append(row)