摘要:筆試問(wèn)題如何使用讀取個(gè)大小的文件這個(gè)問(wèn)題其實(shí)在筆試中會(huì)經(jīng)常遇到的個(gè)題目。解決方案在中除了使用方法讀取文件內(nèi)容外還有另外個(gè)方法和也可以進(jìn)行內(nèi)容的讀取。結(jié)果發(fā)現(xiàn)使用的方式還是會(huì)導(dǎo)致內(nèi)存不足的情況發(fā)生而通過(guò)讀取指定字節(jié)的方式則可以處理完這個(gè)文件。
筆試問(wèn)題
如何使用Python讀取1個(gè)8GB大小的文件,這個(gè)問(wèn)題其實(shí)在筆試中會(huì)經(jīng)常遇到的1個(gè)題目。對(duì)于在Python中讀取文件的操作,一般我們會(huì)這樣來(lái)操作:
f = open("filename","rb") f.read()
下面我們來(lái)找1個(gè)比較大的文件,比如1個(gè)nginx的日志文件,記得之前有一次公司的1天的nginx日志文件解壓為3GB大小,不得不對(duì)其進(jìn)行切分。
發(fā)現(xiàn)問(wèn)題這里我們找到了1個(gè)3G大小的文件。接下來(lái),我們使用普通的讀取方式來(lái)查看該文件的內(nèi)容:
f=open("test","rb") data=f.read() --------------------------------------------------------------------------- MemoryError Traceback (most recent call last) ... MemoryError:
我們可以看到1個(gè)MemoryError的錯(cuò)誤,說(shuō)明該無(wú)文件無(wú)法被裝載在內(nèi)存中發(fā)生溢出了。
下面我們來(lái)思考下為什么內(nèi)存會(huì)溢出了,在我們打開文件的時(shí)候并沒(méi)有發(fā)生任何異常,而在我們調(diào)用read方法時(shí)才出現(xiàn)問(wèn)題。我們知道,文件對(duì)象的read方法會(huì)嘗試將所有內(nèi)容以1行的形式讀入,顯然這種方式對(duì)于大文件是不可行的。
在Python中,除了使用read方法讀取文件內(nèi)容外,還有另外2個(gè)方法readline和readlines也可以進(jìn)行內(nèi)容的讀取。
既然默認(rèn)read方法是一次性的將內(nèi)容都讀取到內(nèi)存中,那么我們是否可以指定其每次讀取的長(zhǎng)度來(lái)解決這個(gè)問(wèn)題呢?
data = f.read(1024) while 1: #處理該行的代碼 data = f.read(1024)
而readlines會(huì)返回每1行讀取的內(nèi)容的列表,因此有一定風(fēng)險(xiǎn)的。
for l in f.readlines(): #處理這1行的代碼
那么,我們每次讀取1行總可以了把。這樣我們可以通過(guò)如下的方式來(lái)進(jìn)行:
line = f.readline() while 1: #處理該行的代碼 line = f.readline()
我們通過(guò)1個(gè)無(wú)限循環(huán)的方式來(lái)進(jìn)行讀取。結(jié)果發(fā)現(xiàn),使用readlines的方式還是會(huì)導(dǎo)致內(nèi)存不足的情況發(fā)生,而通過(guò)讀取指定字節(jié)的方式則可以處理完這個(gè)文件。
在上面的解決方案中,我們需要手動(dòng)處理文件讀取的大小,并在合適的情況退出讀取的操作。
那么,我們有沒(méi)有更好的解決方案呢?實(shí)際上是有的,在Python的手冊(cè)中,有1個(gè)xreadlines的方法,這個(gè)方法就類比range和xrange函數(shù)的區(qū)別。這個(gè)方法返回類似iter(f)的字符串,但是遺憾的是該方法在Python版本2.3中已經(jīng)被淘汰了,官方建議我們使用for語(yǔ)句來(lái)替代:
for line in f: #處理該行的代碼
通過(guò)這種方式,Python將處理文件對(duì)象為1個(gè)迭代器,并自動(dòng)使用緩存IO和內(nèi)存管理,這樣我們就不需要關(guān)注大的文件了。
參考文件:
http://stackoverflow.com/questions/8009882/how-to-read-large-file-line-by-line-in-python
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37964.html
摘要:內(nèi)容列表元組操作字符串操作字典操作集合操作文件操作字符編碼與轉(zhuǎn)碼內(nèi)置函數(shù)在中,最基本的數(shù)據(jù)結(jié)構(gòu)是序列。序列中的每個(gè)元素被分配一個(gè)序號(hào)即元素的位置,也稱為索引??兆值洳话ㄈ魏雾?xiàng)由兩個(gè)大括號(hào)組成。 day2內(nèi)容1、列表、元組操作2、字符串操作3、字典操作4、集合操作5、文件操作6、字符編碼與轉(zhuǎn)碼7、內(nèi)置函數(shù) 在Python中,最基本的數(shù)據(jù)結(jié)構(gòu)是序列(sequence)。序列中的每個(gè)元素被...
摘要:最近在學(xué)習(xí)網(wǎng)絡(luò)爬蟲,完成了一個(gè)比較簡(jiǎn)單的網(wǎng)絡(luò)爬蟲。網(wǎng)絡(luò)爬蟲,可以理解為自動(dòng)幫你在網(wǎng)絡(luò)上收集數(shù)據(jù)的機(jī)器人。網(wǎng)絡(luò)爬蟲簡(jiǎn)單可以大致分三個(gè)步驟第一步要獲取數(shù)據(jù),第二步對(duì)數(shù)據(jù)進(jìn)行處理,第三步要儲(chǔ)存數(shù)據(jù)。 最近在學(xué)習(xí)網(wǎng)絡(luò)爬蟲,完成了一個(gè)比較簡(jiǎn)單的python網(wǎng)絡(luò)爬蟲。首先為什么要用爬蟲爬取信息呢...
摘要:概述如果程序處理的數(shù)據(jù)比較多比較復(fù)雜,那么在程序運(yùn)行的時(shí)候,會(huì)占用大量的內(nèi)存,當(dāng)內(nèi)存占用到達(dá)一定的數(shù)值,程序就有可能被操作系統(tǒng)終止,特別是在限制程序所使用的內(nèi)存大小的場(chǎng)景,更容易發(fā)生問(wèn)題。下面我就給出幾個(gè)優(yōu)化占用內(nèi)存的幾個(gè)方法。 概述 如果程序處理的數(shù)據(jù)比較多、比較復(fù)雜,那么在程序運(yùn)行的時(shí)候,會(huì)占用大量的內(nèi)存,當(dāng)內(nèi)存占用到達(dá)一定的數(shù)值,程序就有可能被操作系統(tǒng)終止,特別是在限制程序所使用...
閱讀 2808·2023-04-25 18:06
閱讀 2604·2021-11-22 09:34
閱讀 1697·2021-11-08 13:16
閱讀 1323·2021-09-24 09:47
閱讀 3059·2019-08-30 15:44
閱讀 2784·2019-08-29 17:24
閱讀 2597·2019-08-23 18:37
閱讀 2446·2019-08-23 16:55