2014-03-28 163 views
3

我需要查找包含特定字符串的文本文件的所有行,並將每行寫入不同的文本文件。如何改進我的代碼以防止讀取大型文本文件(6GB大小)的第一個5,000,000,000行時系統崩潰?編譯代碼後,我的電腦運行緩慢,並突然凍結。即使我停止編譯過程,內存仍然被佔用,並出現相同的問題。我的IDE是Spyder,我使用Python 2.7。 謝謝!Python for循環導致系統崩潰

我的代碼是:

import fileinput 

ot = 'N' 
j = 1 
i = 1 
string = "ABCD" 

for line in fileinput.input(['/../myfile.txt']): 
    if i<=5000000000: 
     if string in line: 
      output = open(ot + str(j) + '.txt', 'w') 
      output.write(line) 
      output.close() 
      j += 1 
     i += 1 
+1

嘗試使用'背景manager':'在開線( 'file.txt的', 'R'):' – sshashank124

+0

如果你嘗試讀取50MB的文件,有什麼結果呢? –

+0

@黃建偉,代碼最大工作爲i = 1,000,000,小文本文件例如250MB,但超過他們我的系統顯示沒有足夠的內存(我的操作系統是UBUNTU 13.10和我的電腦的內存是8GB)。 –

回答

5

你可以試試這個代碼:

file_input = open('mhyfile.txt','r') 
for line in file_input: 
    #Your code here 

for line in file_input:循環將逐行讀取文件中的行。但我在我的linux系統中測試並發現fileinput.input()不再使用內存。我認爲你應該提供更多關於你的問題的信息。

一個可能的問題是您將太多文件寫入磁盤並導致系統崩潰。您可以嘗試將選定的行寫入單個文件並標記行號j

-1

試試這個:

file_num = 1 

with open('myfile.txt', 'r') as file: 
    for i in range(5000000000): 
     if file.readline(i) == 'ABCD': 
      with open('N' + file_num + '.txt', 'w') as write_file: 
       write_file.write(file.readline(i)) 
       file_num += 1 

不知道如何以及它很好地崩潰幫助,但它是乾淨多了。在下面提問。

+0

我得到這個錯誤「爲我在範圍內(5000000000):MemoryError」 –

+0

@Emely_sh嘗試'xrange'而不是 – Broseph

+2

嗨,只是一個建議,不要使用「文件」關鍵字作爲您的文件處理程序。此外,你可以迭代文件而不調用「file.readline(i)」。和file.readline(i)=='ABCD'是錯誤的。該操作正在檢查包含「ABCD」的行,而不是該行是「ABCD」。此外,讀取用於打開文件的默認模式,因此標誌'r'是冗餘的。 – lightalchemist

3
from itertools import izip 
ot = 'N%d.txt' 
j = 1 
lim = 5*10**9 
with open('myfile.txt') as f: 
    #the xrange part replaces the i < 5e9 thing you had. 
    for line, _ in izip(f,xrange(lim)): 
     if 'ABCD' in line: 
      output = open(ot % j, 'w') 
      output.write(line) 
      output.close() 
      j += 1 

這應該運行良好,但它可能需要一段時間,如果您的文件很大,但它不應占用太多的內存。

編輯
我添加了izip以避免吞噬大量的內存。 izip就像zip一樣,除了它返回一個生成器而不是列表。

+0

非常感謝你的工作! –

+0

@Emely_sh其實,我認爲這可能會使所有內容加載內存?大聲笑。如果是這樣,我不知道爲什麼它的工作時,其他人不知道。在python3中,zip會返回一個zip對象,然後懶惰地給每個項目迭代。但是在python 2中,我認爲這只是迫使第一個,最多50億條線條成爲元組列表。如果文件足夠大,它應該吃掉大量的內存。 – Broseph

+0

我的電腦沒有使用zip壓縮過程,但它比izip慢; izip只使用了14%的內存:)謝謝 –

1

的正規途徑選擇只是第限制項目迭代器是使用islice從 itertools - islice(my_file, limit)類似於my_file.readlines()[:limit],但它避免在讀取整個文件到內存中。只計算它們中給定字符串的行數只會稍微複雜一些:使用生成器表達式來獲取這些行,然後是那些

from itertools import islice 
ot = 'N%d.txt' 
limit = 5000000000 

with open('myfile.txt') as f: 
    lines = (line for line in f if 'ABCD' in line) 
    for j, line in enumerate(islice(lines, limit), start=1): 
     with open(it % j, 'w') as out: 
      out.write(line)