2012-03-28 66 views
11

我遇到了一個問題,我沒有看到任何人在StackOverflow遇到甚至谷歌的事情。Python不會讀整個文本文件

我的主要目標是能夠用另一個字符串替換文件中字符串的出現次數。有沒有一種方法可以訪問文件中的所有行。

問題是,當我嘗試讀取大文本文件(1-2 gb)的文本時,python只讀取它的一個子集。

例如,我會做一個非常簡單的命令,如:

newfile = open("newfile.txt","w") 
f = open("filename.txt","r") 
for line in f: 
    replaced = line.replace("string1", "string2") 
    newfile.write(replaced) 

而且只寫原始文件的第一個382 MB。有沒有人以前遇到過這個問題?

我嘗試了一些不同的解決方案,如使用:

import fileinput 
for i, line in enumerate(fileinput.input("filename.txt", inplace=1) 
    sys.stdout.write(line.replace("string1", "string2") 

但它也有同樣的效果。也不讀取數據塊文件,如使用

我已經將範圍縮小到最有可能是在問題一讀,而不是寫問題,因爲它發生了簡單的打印出線條。我知道還有更多的線條。當我在Vim這樣的全文本編輯器中打開它時,我可以看到最後一行應該是什麼,並且它不是python打印的最後一行。

任何人都可以提供任何建議或嘗試的東西嗎?

我目前使用的是Windows XP的32位版本的RAM的3.25 GB和運行的Python 2.7

*編輯發現的解決方案(感謝Lattyware)。使用迭代

def read_in_chunks(file, chunk_size=1000): 
    while True: 
     data = file.read(chunk_size) 
     if not data: break 
     yield data 
+1

一行一行地讀取迭代器應該是一個懶惰的操作,所以它應該工作,不管文件的大小。雖然它不應該影響你的情況,但是在打開文件時你也會想用''with'' - 這是一個很好的做法,而不是正確地處理異常情況下的關閉。 – 2012-03-28 10:49:25

+0

工作很好!非常感謝。 *編輯:我嘗試在這裏發佈迭代器代碼,但它不會格式化,所以我將它添加到原始文章中。 – user1297872 2012-03-28 11:08:39

+0

你用不同的大文本文件試過了嗎?有沒有382mb中的文件有些奇怪 - 一些奇怪的字符被視爲文件的結尾? – neil 2012-03-28 11:13:40

回答

1

如果使用這樣的文件:

with open("filename.txt") as f: 
    for line in f: 
     newfile.write(line.replace("string1", "string2")) 

它應該只在一個時間讀入內存一條線,除非你保持在內存中該行的參考。
每行讀完後,它將由python的垃圾收集器來擺脫它。試試這個,看看它是否適合你:)

22

嘗試:

f = open("filename.txt", "rb") 

在Windows上,rb意味着以二進制模式打開的文件。根據文檔,文本模式與二進制模式僅對行尾字符有影響。但是(如果我沒有記錯的話)我相信在Windows上以文本模式打開文件也會對EOF(十六進制1A)做些什麼。

您也可以使用fileinput時指定的模式:

fileinput.input("filename.txt", inplace=1, mode="rb") 
+0

這也適用!我最喜歡這個解決方案,因爲改變現有代碼有多容易。 – user1297872 2012-03-28 11:20:42

+0

如何有「那也行得通」?這顯然是你的問題。還有什麼其他方法可以工作?嗯,我在評論中看到,指定要讀取的字節長度,而不是使用「readline」 – jsbueno 2012-03-28 12:27:14

+0

真棒,爲我工作 – Stoyan 2014-04-21 10:43:17

2

你確定這個問題是閱讀而不是用寫出來? 您是否關閉了寫入的文件,明確地爲newfile.close()或使用with構造?

不關閉輸出文件通常是在緩衝進行到某處時出現此類問題的根源。如果您的設置也是如此,關閉應該修復您的初始解決方案。