初级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)
指向文件的开头