初级Python:在同一个fi上读写

2024-06-16 10:00:46 发布

您现在位置: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()

我会努力澄清我的问题。在上面的例子中,open file是用来打开文件的对象。如果我想第一次给它写信,我没有问题。如果我想使用相同的openFile来读取文件或在其中附加一些内容。它不会发生,也不会出现错误。在对同一个文件执行另一个读/写操作之前,我必须声明相同/不同的open file对象。

#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()

如果有人能告诉我我在这里做错了什么,或者这只是一件Python的事情,我将不胜感激。我正在使用Python2.7。谢谢!


Tags: 文件对象testcloseread错误openfile
3条回答

读取和写入发生在当前文件指针所在的位置,每次读取/写入都会前进。 在您的特定情况下,写入openFile,会导致文件指针指向文件的结尾。试着从结尾读会导致EOF。 您需要重置文件指针,以便在读取之前通过seek(0)指向文件的开头

更新的响应:

这似乎是Windows特有的一个bug-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())

介于read()和write()之间。

我的原始响应演示了如何在打开的用于追加工作的同一文件上进行读/写。如果你用的是Windows,那显然不是真的。

原始响应

在“r+”模式下,使用write方法将根据指针的位置将字符串对象写入文件。在您的例子中,它将把字符串“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

每个打开的文件都有一个隐式指针,该指针指示数据的读写位置。通常这默认为文件的开头,但如果使用a(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,替换现有的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的更多信息。

相关问题 更多 >