最近處理文本文檔時(文件約2GB大小),出現memoryError
錯誤和文件讀取太慢的問題,后來找到了兩種比較快Large File Reading
的方法,本文將介紹這兩種讀取方法。
Preliminary
我們談到“文本處理”時,我們通常是指處理的內容。Python 將文本文件的內容讀入可以操作的字符串變量非常容易。文件對象提供了三個“讀”方法: .read()
、.readline()
和 .readlines()
。每種方法可以接受一個變量以限制每次讀取的數據量,但它們通常不使用變量。 .read()
每次讀取整個文件,它通常用於將文件內容放到一個字符串變量中。然而 .read()
生成文件內容最直接的字符串表示,但對於連續的面向行的處理,它卻是不必要的,並且如果文件大於可用內存,則不可能實現這種處理。下面是read()
方法示例:
try: f = open('/path/to/file', 'r') print f.read() finally: if f: f.close()
調用read()
會一次性讀取文件的全部內容,如果文件有10G,內存就爆了,所以,要保險起見,可以反復調用read(size)
方法,每次最多讀取size個字節的內容。另外,調用readline()
可以每次讀取一行內容,調用readlines()
一次讀取所有內容並按行返回list。因此,要根據需要決定怎么調用。
如果文件很小,read()
一次性讀取最方便;如果不能確定文件大小,反復調用read(size)
比較保險;如果是配置文件,調用readlines()
最方便:
def process(str) print(str) for line in f.readlines(): process(line) # <do something with line>
1.Read In Chunks
處理大文件是很容易想到的就是將大文件分割成若干小文件處理,處理完每個小文件后釋放該部分內存。這里用了 iter & yield
:
def read_in_chunks(filePath, chunk_size=1024*1024): """ Lazy function (generator) to read a file piece by piece. Default chunk size: 1M You can set your own chunk size """ file_object = open(filePath) while True: chunk_data = file_object.read(chunk_size) if not chunk_data: break yield chunk_data if __name__ == "__main__": filePath = './path/filename' for chunk in read_in_chunks(filePath): process(chunk) # <do something with chunk>
或者
file = open("sample.txt")
while 1:
lines = file.readlines(100000)
if not lines:
break
for line in lines:
pass # do something
2.Using with open()
python中用with語句打開和關閉文件,包括了拋出一個內部塊異常,並且,for line in f其實是將文件對象f視為一個迭代器,自動的采用緩沖IO和內存管理,所以不必擔心大文件。讓系統來處理,其實是最簡單的方式,交給解釋器
#If the file is line based with open(...) as f: for line in f: process(line) # <do something with line>