2011-06-23 65 views
0

我想在我的Python腳本中加載約2GB的文本文件(大約35K文件)。在page.read()方法的三分之一左右出現內存錯誤。我'Python MemoryError加載文本文件

for f in files: 
    page = open(f) 
    pageContent = page.read().replace('\n', '') 
    page.close() 

    cFile_list.append(pageContent) 

我從來沒有在Python中處理過這種大小的對象或進程。我檢查了一些其他Python MemoryError相關的線程,但我無法解決我的情況。希望有些東西可以幫助我。

+3

你會想要讀取輸入的塊。看看這個問題的答案:http://stackoverflow.com/questions/519633/lazy-method-for-reading-big-file-in-python –

+1

如果你使用的是64位機器,試試使用64位Python構建。 – geoffspear

+0

我不明白你爲什麼要加載cFile_list中所有文件的所有內容。究竟想要如何處理文件的內容? 我想也許你想在將'\ n'替換爲''後將每個文件的內容保存到另一個相應的文件中。如果這是你想要做的,那麼你可以在for循環中將內容保存到它自己的新文件中,然後無論你做多少文件,都不會得到任何內存錯誤。 –

回答

2

您試圖一次加載太多內存到內存中。這可能是因爲進程大小限制(特別是在32位操作系統上),或者因爲您沒有足夠的內存。

64位操作系統(和64位的Python)將能夠做到這一點確定給予足夠的RAM,但也許你可以簡單地改變你的程序工作,所以該方法並不是每一頁都在RAM中的一次。

什麼是用於cFile_list?你是否真的需要同時在內存中的所有頁面?

+0

cFile_list是一個大文檔列表。它最終成爲Naive Bayes分類器的訓練和測試集。只要內存中的所有內容都不在同一時間,另一種方法是什麼? – Greg

+1

@Greg,你可以改變你的程序來遍歷_filenames_。對於每個文件名,請閱讀文件,清理文件,將文件提供給分類器,關閉文件。這樣一次只有一個文件需要在內存中。 –

1

考慮使用發電機,如果可能的話,你的情況:

file_list = [] 
for file_ in files: 
    file_list.append(line.replace('\n', '') for line in open(file_)) 

file_list中現在是迭代器是名單更多的內存效率比讀取每個文件的全部內容爲一個字符串。一旦上課,你需要一個特定的文件的整串,你可以做

string_ = ''.join(file_list[i]) 

注意,但是,遍歷file_list中只能一次由於在Python迭代器的性質。

關於發電機更多詳細信息,請參閱http://www.python.org/dev/peps/pep-0289/

+0

好的謝謝。我能夠加載所有文件,但是當我嘗試執行加入時,出現以下情況: ValueError:關閉文件上的I/O操作 – Greg

+0

我的錯:文件將在範圍之外關閉。我編輯了代碼。請注意,您還應該確保打開文件不會失敗。 – jena

0

這是不讀內存中的文件全部有效途徑。

正確的方法 - 習慣索引。

首先需要完成每行的開始位置的字典(關鍵是行號,和值 - 累積以前行長度)。

t = open(file,’r’) 
dict_pos = {} 

kolvo = 0 
length = 0 
for each in t: 
    dict_pos[kolvo] = length 
    length = length+len(each) 
    kolvo = kolvo+1 

和最終目標函數:

def give_line(line_number): 
    t.seek(dict_pos.get(line_number)) 
    line = t.readline() 
    return line 

t.seek(LINE_NUMBER) - ,其執行文件最多行開始的修剪指令。所以,如果你下一次提交readline - 你會獲得你的目標線。 使用這種方法(直接處理文件的必要位置而無需運行整個文件),您可以節省大量時間並處理大量文件。