2013-10-03 31 views
0

我目前正在處理我的第一個Python項目,並且需要通過2GB文件進行解析。 我發現,如果我去了一行行那將是非常非常慢... 然而緩衝方法,使用:在Python中通過大文件搜索字符串

f = open(filename)     
lines = 0 
buf_size = 1024 * 1024 
read_f = f.read 
buf = read_f(buf_size) 
while buf: 
    for line in buf: 
     #code for string search 
     print line 
    buf = read_f(buf_size) 

這裏打印線不打印「線」,它每行只打印一個字符。所以我有問題做子串查找... 請幫助!

+1

「for line」與文件一起工作,因爲文件迭代器的構建是爲了將輸入分解爲行。你在這裏創建的字符串迭代器是爲了將字符串分解成字符而構建的。使用更大的文件緩衝區可以獲得更好的性能,但我無法對此做出任何承諾!返回逐行迭代文件並嘗試使用128K緩衝區'open(filename,「r」,128 * 1024)'。 – tdelaney

+0

注意:你可以使用['iter(callable,sentinel)'](http://docs.python.org/3/library/functions.html#iter)來避免while循環: (lambda:f.read(1024 * 1024),''):#搜索子字符串。在這種情況下,'iter'將創建一個迭代器,調用它的'callable'參數(即'callable()')直到找到'sentinel'值。無論如何,閱讀2GB文件*將需要一些時間。假設您的硬盤可以以200 MB/s的速度讀取,至少需要10個secons *,我相信硬盤通常在50到150 MB/s之間! – Bakuriu

回答

0

print line打印一個字符,因爲buf是一個字符串,並且遍歷字符串會將該字符串的字符作爲一個字符的字符串。

當你說逐行閱讀很慢時,你是如何實現閱讀的?如果您使用readlines(),則可以解釋緩慢(參見http://stupidpythonideas.blogspot.com/2013/06/readlines-considered-silly.html)。

文件是在他們行迭代,和Python會選擇進行遍歷時,緩衝區大小,所以這可能會滿足您的需求:如果要手動指定緩衝區大小

for line in f: 
    # do search stuff 

,你也可以這樣做:

buf = f.readlines(buffersize) 
while buf: 
    for line in buf: 
     # do search stuff 
    buf = f.readlines(buffersize) 

雖然,兩者中的第一個通常更好。

+0

謝謝,看起來像我誤解了什麼是buf。如果我確實這麼做'for line in f:'迭代2G文件需要2分鐘左右。這可以減少更多嗎? –

+0

如果您不介意將內存丟到風中,您可以對該文件進行mmap映射。 (請參閱http://stackoverflow.com/questions/8151684/how-to-read-lines-from-mmap-file-in-python)。除此之外,您可以手動嘗試更改緩衝區大小。 – Cookyt

0

的問題是,BUF是一個字符串...

說BUF = 「ABCD」

這意味着,BUF [0] = A,BUF [1] = B等。

for line in buf: 
    print line 

會導致 一個 b Ç d

這意味着在你的for循環,你不循環了「線」,但在BUF字符串的所有元素。您可以使用readlines或通過查找「\ n」將緩衝區分割爲單行。

+0

你的意思是類似於'buf中的行:l = line.readline()'? –

+0

@MojingLiu不,他的意思是'在buf.split('\ n')'中換行。 – Bakuriu