初级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。 谢谢!

更新回应

这看起来像一个特定于Windows的错误 – http://bugs.python.org/issue1521491

http://mail.python.org/pipermail/python-bugs-list/2005-August/029886.html上解释的解决方法引用;

除非在它们之间发生文件定位操作(例如seek()),否则混合读取和写入打开文件的效果是完全不确定的。 我猜不出你期望会发生什么,但似乎最有可能通过插入可靠地获得你想要的东西

fp.seek(fp.tell())

read()和write()之间。

我最初的回应显示了如何在同一个文件上打开附加作品的读/写。 如果你使用Windows,显然是不正确的。

原始回应

在“r +”模式下,使用写入方法将根据指针所在的位置将string对象写入文件。 在你的情况下,它会将string“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' 

string“foooooooooooooo”附加在文件的末尾,因为指针已经在文件的末尾。

你在一个区分二进制和文本文件的系统吗? 在这种情况下,你可能想使用'rb +'作为模式。

在区分二进制和文本文件的系统上,以二进制模式打开文件的方式附加'b'; 在没有这个区别的系统上,添加'b'没有任何作用。 http://docs.python.org/2/library/functions.html#open

每个打开的文件都有一个隐含的指针,指示数据将被读取和写入的位置。 通常这个默认是文件的开始,但是如果你使用(append)的模式,那么它默认是文件的结尾。 另外值得一提的是,即使在模式中添加+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覆盖下三个字符,replace现有的字符。

您可以使用文件的seek()方法跳转到特定点。 在上面的例子之后,如果执行了以下操作:

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

然后你会发现文件现在包含This IS a TEST file.

所有这些都适用于Unix系统,您可以testing这些示例来确保。 但是,在Windows系统上混合使用read()write()时遇到了问题。 例如,当我在我的Windows机器上执行第一个例子时,它正确地打印This ,但是当我检查文件之后, write()已经被完全忽略。 然而,第二个例子(使用seek() )似乎在Windows上正常工作。

总之,如果你想从Windows中的文件中间读/写,我build议总是使用明确的seek()而不是依靠读/写指针的位置。 如果你只读或只写,那么它是非常安全的。

最后一点 – 如果您将Windows上的path指定为文字string,请记住要跳过您的反斜杠:

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

或者你可以在开始时使用原始string:

 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+") 

你可以在官方的Python文档中find关于文件IO的更多信息。

读和写发生在当前文件指针位置,并且随着每个读/写而前进。 在你的特定情况下,写入openFile ,使文件指针指向文件的结尾。 尝试从最后读取将导致EOF。 您需要重置文件指针,才能在读取文件之前通过seek(0)指向文件的开头