python 讀取大檔案

2021-07-24 17:42:00 字數 1987 閱讀 5506

以前一直沒有關注過python讀取大檔案的問題,因為一直都是順順暢暢地讀取了檔案。直到今天有人問我python怎麼讀取檔案出現了記憶體不足的錯誤?我才發現原來大檔案(gb級別)的讀取和普通檔案的讀取是不一樣的。

下面介紹三種我親測可用的方法。這裡的檔案型別可以是txt,dat等型別的檔案。

用read(size)方法

用iter和yield分段分段地讀

用with open()

方法一read(size)

try:

f = open('/path/to/file', 'r')

print f.read(size) #size表示一次讀取的最大位元組數

finally:

if f:

f.close()

呼叫read()會一次性讀取檔案的全部內容,如果檔案有10g,記憶體就爆了,所以,要保險起見,可以反覆呼叫read(size)方法,每次最多讀取size個位元組的內容。另外,呼叫readline()可以每次讀取一行內容,呼叫readlines()一次讀取所有內容並按行返回list。因此,要根據需要決定怎麼呼叫。

如果檔案很小,read()一次性讀取最方便;如果不能確定檔案大小,反覆呼叫read(size)比較保險;如果是配置檔案,呼叫readlines()最方便。

方法二用 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)

ifnot chunk_data:

break

yield chunk_data

if __name__ == "__main__":

filepath = './path/filename'

for chunk in read_in_chunks(filepath):

process(chunk) #

這裡的yield只要知道:當你呼叫這個函式的時候,函式內部的**並不立馬執行 ,這個函式只是返回乙個生成器物件,對這個生成器物件進行迭代可以實現對大檔案進行分割成小檔案進行讀取。
方法三用with open()

#if the file is line based

with open(...) as f:

for line in f:

process(line) #

with語句開啟和關閉檔案,包括丟擲乙個內部塊異常。for line in f檔案物件f視為乙個迭代器,會自動的採用緩衝io和記憶體管理,所以你不必擔心大檔案。
注意

前兩種方法都是用分割大檔案成小檔案進行操作的,所以需要注意的是,在檔案的分割造成的斷點處做字元編譯碼時小心處理。一種可行的處理方法是:前乙個小檔案不全解析完,解析一部分,到標誌性的結尾處停止,然後拼接後乙個小檔案再做解析。

舉個例子:如果你以1m來分割大檔案,檔案的編碼是gbk,那麼乙個字元的大小是兩個位元組,但是乙個空格的大小似乎只是乙個位元組,那麼你就不能確定你這1024*1024的位元組是不是正好是完整的字串了,所以你可以解碼到【快要接近尾聲的空格處停下,空格的位元組碼是0x20】,然後把剩下的位元組與下乙個檔案拼接再進行同樣的解碼處理。

python讀取大檔案

最近在學習python的過程中接觸到了python對檔案的讀取。python讀取檔案一般情況是利用open 函式以及read 函式來完成 f open filename,r f.read 這種方法讀取小檔案,即讀取遠遠大小小於記憶體的檔案顯然沒有什麼問題。但是如果是將乙個10g大小的日誌檔案讀取,即...

python讀取大檔案 python讀取大檔案

python讀取檔案對各列進行索引 可以用readlines,也可以用readline,如果是大檔案一般就用readlined a in open testfile.txt r for line in a in columnssplit line.rstrip split d columnsspli...

python 大檔案的讀取

在這裡插入 片很久以前做數學建模的時候面臨了一回大檔案的讀取問題,當時沒有什麼程式設計經驗就使用如下的 進行了讀取。with open filename,rb as fp for line in fp.readlines do something line 這種 在檔案比較小時倒也沒有太大影響,但是...