2013-01-11 67 views
17

一週前開始Python,我有一些問題需要關於讀取和寫入相同的文件。我在網上瀏覽了一些教程,但我仍然對此感到困惑。我可以理解簡單的讀寫文件。初學者Python:讀取和寫入同一個文件

openFile = open("filepath", "r") 
readFile = openFile.read() 
print readFile 

openFile = open("filepath", "a") 
appendFile = openFile.write("\nTest 123") 

openFile.close() 

但是,如果我嘗試以下,我會在我寫入的文本文件中出現一堆未知文本。任何人都可以解釋爲什麼我得到這樣的錯誤,爲什麼我不能以下面顯示的方式使用相同的openFile對象。

# I get an error when I use the codes below:  
openFile = open("filepath", "r+") 
writeFile = openFile.write("Test abc") 

readFile = openFile.read() 
print readFile 

openFile.close() 

我會盡力澄清我的問題。在上面的例子中,openFile是用來打開文件的對象。如果我想第一次寫信,我沒有問題。如果我想使用相同的openFile來讀取文件或附加內容。它不會發生或發生錯誤。我必須聲明相同/不同的打開文件對象,然後才能對同一文件執行另一個讀/寫操作。

#I have no problems if I do this:  
openFile = open("filepath", "r+") 
writeFile = openFile.write("Test abc") 

openFile2 = open("filepath", "r+") 
readFile = openFile2.read() 
print readFile 

openFile.close() 

如果有人能告訴我我在這裏做錯了什麼,或者它只是一個Pythong的事情,我將不勝感激。我正在使用Python 2.7。謝謝!

回答

18

更新的響應閱讀之前重置文件指針,指向文件的開頭:

這似乎是一個特定於Windows的錯誤 - http://bugs.python.org/issue1521491

從解決方法引用在http://mail.python.org/pipermail/python-bugs-list/2005-August/029886.html

the effect of mixing reads with writes on a file open for update is entirely undefined unless a file-positioning operation occurs between them (for example, a seek()). I can't guess what you expect to happen, but seems most likely that what you intend could be obtained reliably by inserting

fp.seek(fp.tell())

讀()和你寫說明()。

我的原始回覆演示瞭如何在同一個文件上打開附加作品的讀/寫。如果您使用Windows,顯然不是這樣。

原始響應

在「R +」模式中,使用寫入方法將寫基於其中指針在字符串對象到該文件。在你的情況下,它會將字符串「Test abc」附加到文件的開頭。請參見下面的例子:

>>> f=open("a","r+") 
>>> f.read() 
'Test abc\nfasdfafasdfa\nsdfgsd\n' 
>>> f.write("foooooooooooooo") 
>>> f.close() 
>>> f=open("a","r+") 
>>> f.read() 
'Test abc\nfasdfafasdfa\nsdfgsd\nfoooooooooooooo' 

字符串「foooooooooooooo」在文件末尾附加得到了自指針已經在文件的結尾。

您是否在區分二進制和文本文件的系統上?在這種情況下,您可能想使用'rb +'作爲模式。

Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that don’t have this distinction, adding the 'b' has no effect. http://docs.python.org/2/library/functions.html#open

+0

這是奇怪的部分。如果我嘗試這些行,似乎出現錯誤:f = open(「C:\ Users \ MooMoo \ Desktop \ clothes.txt」,「r +」)012.fmtoooooooooo 「)。我得到的錯誤信息:Traceback(最近一次調用最後一次): 文件「C:\ Users \ MooMoo \ Desktop \ Python27 \ PyProject \ src \ test.py」,第43行, f.write(「foooooooooooooo」 ) IOError:[Errno 0] Error f.close() – Cryssie

+0

這看起來像是一個特定於Windows的問題。我正在更新我的回覆。要點:在寫之前使用f.seek(f.tell())。 – sidi

2

在當前文件指針位置發生讀寫時,會隨着每次讀/寫而前進。 在您的特定情況下,寫入openFile會導致文件指針指向文件結尾。嘗試從最後讀取將導致EOF。 您需要通過seek(0)從中

5

每個打開的文件都有一個隱式指針,它指示將讀取和寫入數據的位置。通常情況下,這默認爲文件的開頭,但如果使用a(追加)模式,則默認爲文件的結尾。值得注意的是,即使您將+添加到模式,w模式也會截斷您的文件(即刪除所有內容)。

無論您何時讀取或寫入N個字符,讀/寫指針都會在文件內向前移動該數量。如果你還記得那些,我覺得這有點像舊的盒式磁帶。所以,如果你執行以下代碼:

fd = open("testfile.txt", "w+") 
fd.write("This is a test file.\n") 
fd.close() 

fd = open("testfile.txt", "r+") 
print fd.read(4) 
fd.write(" IS") 
fd.close() 

...它應該結束了打印This然後離開文件,內容爲This IS a test file.。這是因爲初始read(4)返回文件的前4個字符,因爲指針位於文件的開頭。它將指針留在This後面的空格字符處,因此以下write(" IS")將用空格(與已存在的空間相同)覆蓋下三個字符,然後用IS替換現有的is

您可以使用文件的seek()方法跳轉到特定點。上面的例子後,如果您執行以下操作:

fd = open("testfile.txt", "r+") 
fd.seek(10) 
fd.write("TEST") 
fd.close() 

...然後你會發現文件現在包含This IS a TEST file.

這一切都適用於Unix系統,您可以測試這些示例來確保。但是,我在Windows系統上遇到混合read()write()的問題。例如,當我在Windows機器上執行第一個示例時,它正確地打印This,但是當我檢查文件後,write()已被完全忽略。但是,第二個示例(使用seek())似乎在Windows上正常工作。總之,如果你想從Windows中的文件中讀取/寫入,我建議總是使用明確的seek()而不是依賴於讀/寫指針的位置。如果你只讀或只寫,那麼它是非常安全的。

最後一點 - 如果你在Windows上指定路徑爲文字字符串,記得來逃避反斜槓:

fd = open("C:\\Users\\johndoe\\Desktop\\testfile.txt", "r+") 

或者,您可以把一個r在開始使用原始字符串:

fd = open(r"C:\Users\johndoe\Desktop\testfile.txt", "r+") 

或者最便攜的選擇是使用os.path.join()

fd = open(os.path.join("C:\\", "Users", "johndoe", "Desktop", "testfile.txt"), "r+") 

你可以在official Python docs找到更多關於文件IO的信息。

+0

Hey Cartroo,不幸的是,我似乎理解你的代碼,但是當我編譯時,它不會給你我給你的東西。例如,我遵循你在第一組示例中給出的確切代碼集。當我檢查文件時,文件中的文本只顯示「這是一個測試文件」,而不是「這是一個測試文件」。它看起來像寫作不適合我。如果有幫助,我使用Python 2.7。 – Cryssie

+1

從你的評論看來,你正在使用Windows - 就像我在我的回覆中提到的,在同一個文件中混合使用'read()'和'write()'在Windows下似乎不能很好地工作,即使在使用二進制模式 - 恐怕我不太熟悉Windows來說明原因。但是,seek()似乎可以工作,所以在* fd.write(「IS」)行之前加上這行'fd.seek(4)'。明確的seek()似乎讓事情能夠在Windows上運行。如果我可以追蹤有關原始版本無法在Windows上運行的信息,我會在此發佈另一條評論。 – Cartroo

+1

我很好奇,我提交了一個關於它的新的問題,這個具體的行爲:http://stackoverflow.com/questions/14279658/mixing-read-and-write-on-python-files-in-windows – Cartroo