2012-06-18 81 views
3

我試圖打開一個文件並從最後一個讀取點讀取。我的文件相當大(20 Mb到〜1 Gb)經過一番研究後,似乎tell()和seek()將是執行此操作最有效的方法之一。我試過以下代碼如何讓tell()工作

opened = open(filename, "rU") 
f1 = csv.reader(opened) 
k = [] 
for line in f1: 
    k.append(opened.tell()) 

當我這樣做時,列表中的每個值都是8272 Long。這是否意味着我不能使用此實現?有什麼我失蹤?謝謝你的幫助!

我在Windows 7中運行的Python 2.7

更新

拼湊後,這裏的一切教訓和試錯我碰到下面的代碼

opened = open(filename, "rU") 
k = [0] 
where = 1 
for switch in opened: 
    where += len(switch) + 1 
    f = StringIO.StringIO(switch) 
    interesting = csv.reader(f, delimiter=',') 
    good_values = interesting.next() 
    k.append(where) 

return k 

這允許用戶確切地知道文件中要去的地方,同時仍然能夠根據其格式來解析它。我不完全確定爲什麼需要不斷補充偏移量(看來,換行符在len()中沒有被準確計算)。

回答

1

看起來csv.reader正在以8272字節的塊讀取文件,這就是爲什麼你多次從opened.tell()看到這個數字 - 直到我猜你已經讀取了文件中所有在0範圍內的行-8272。之後你會看到8272 * 2幾次,確切的數字將取決於緩衝區讀取行的長度。

因此,基本上,在您的程序中,tell()不會爲您提供新的CSV行的偏移量,正如您似乎認爲的那樣。它只告訴你當前讀取的文件區域末尾的偏移量,該偏移量是由用於實現Python IO功能的系統函數使用的內部OS緩衝區。

+0

所以我迭代了「打開」並添加了字符串的長度。這給了正確的價值。我仍然想使用csv閱讀器,因爲這是我正在閱讀的文件的格式。我正在使用理解來實現它。 比使用正則表達式更有效嗎?有沒有更有效的方法來解決這個問題? T –

+0

不確定你所做的'理解'。如果你有一種方法可以正確地計算給定行的偏移量,爲什麼不重新啓動open.seek來重新啓動上次處理過的csv行之後的文件偏移量,然後將打開的值傳遞給csv.reader構造函數?這應該工作。我不推薦用於處理大型csv文件的正則表達式。 – piokuc

+0

問題是任何使用csv閱讀器會使事情複雜化。我試圖根據csv格式解析文件,但爲了獲得準確的位置數量,我必須將所有字符加起來。我會定期閱讀文件以尋找任何新的更改,這就是爲什麼我想要查找文件脫落的原因。做一個運行計數或將每行作爲原始輸入,然後按照csv格式處理它會更好嗎? –