如何使用Python讀取1個8GB大小的文件,這個問題其實在筆試中會常常遇到的1個題目。對於在Python中讀取文件的操做,通常咱們會這樣來操做:python
f = open('filename','rb') f.read()
下面咱們來找1個比較大的文件,好比1個nginx的日誌文件,記得以前有一次公司的1天的nginx日誌文件解壓爲3GB大小,不得不對其進行切分。nginx
這裏咱們找到了1個3G大小的文件。接下來,咱們使用普通的讀取方式來查看該文件的內容:緩存
f=open('test','rb') data=f.read() --------------------------------------------------------------------------- MemoryError Traceback (most recent call last) ... MemoryError:
咱們能夠看到1個MemoryError的錯誤,說明該無文件沒法被裝載在內存中發生溢出了。
下面咱們來思考下爲何內存會溢出了,在咱們打開文件的時候並無發生任何異常,而在咱們調用read方法時纔出現問題。咱們知道,文件對象的read方法會嘗試將全部內容以1行的形式讀入,顯然這種方式對於大文件是不可行的。函數
在Python中,除了使用read方法讀取文件內容外,還有另外2個方法readline和readlines也能夠進行內容的讀取。
既然默認read方法是一次性的將內容都讀取到內存中,那麼咱們是否能夠指定其每次讀取的長度來解決這個問題呢?日誌
data = f.read(1024) while 1: #處理該行的代碼 data = f.read(1024)
而readlines會返回每1行讀取的內容的列表,所以有必定風險的。code
for l in f.readlines(): #處理這1行的代碼
那麼,咱們每次讀取1行總能夠了把。這樣咱們能夠經過以下的方式來進行:對象
line = f.readline() while 1: #處理該行的代碼 line = f.readline()
咱們經過1個無限循環的方式來進行讀取。結果發現,使用readlines的方式仍是會致使內存不足的狀況發生,而經過讀取指定字節的方式則能夠處理完這個文件。
在上面的解決方案中,咱們須要手動處理文件讀取的大小,並在合適的狀況退出讀取的操做。
那麼,咱們有沒有更好的解決方案呢?其實是有的,在Python的手冊中,有1個xreadlines的方法,這個方法就類比range和xrange函數的區別。這個方法返回相似iter(f)
的字符串,可是遺憾的是該方法在Python版本2.3中已經被淘汰了,官方建議咱們使用for語句來替代:內存
for line in f: #處理該行的代碼
經過這種方式,Python將處理文件對象爲1個迭代器,並自動使用緩存IO和內存管理,這樣咱們就不須要關注大的文件了。 字符串
參考文件:get
http://stackoverflow.com/questions/8009882/how-to-read-large-file-line-by-line-in-python