为什么读取和写入同一个文件会出现问题?

2025-02-25 09:07:00
admin
原创
20
摘要:问题描述:我有一些简单、有效的代码来读取和写入文件:openFile = open("filepath", "r") readFile = openFile.read() print(readFile) openFile = open("filepath&q...

问题描述:

我有一些简单、有效的代码来读取和写入文件:

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

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

openFile.close()

但是,如果我尝试读取和写入同一个文件,我会收到错误,或者生成的文本不是我期望的。例如:

# 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同一个文件使用单独的调用,它似乎可以工作:

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

解决方案 1:

更新后的回应

这看起来像是 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+' 模式下,使用 write 方法将根据指针的位置将字符串对象写入文件。 在本例中,它将字符串“Test abc”附加到文件的开头。 请参阅下面的示例:

>>> f=open("a","r+")
>>> f.read()
'Test abc
fasdfafasdfa
sdfgsd
'
>>> f.write("foooooooooooooo")
>>> f.close()
>>> f=open("a","r+")
>>> f.read()
'Test abc
fasdfafasdfa
sdfgsd
foooooooooooooo'

由于指针已经位于文件末尾,因此字符串“foooooooooooooo”被附加到文件末尾。

您的系统是否区分二进制文件和文本文件?在这种情况下,您可能希望使用“rb+”作为模式。

在区分二进制文件和文本文件的系统上,将“b”附加到模式以二进制模式打开文件;在没有这种区别的系统上,添加“b”不起作用。http
://docs.python.org/2/library/functions.html#open

解决方案 2:

每个打开的文件都有一个隐式指针,指示数据将在何处读取和写入。通常,默认为文件开头,但如果您使用a(append) 模式,则默认为文件结尾。还值得注意的是,即使您向该模式添加内容,该w模式也会截断文件(即删除所有内容) 。+

每当您读取或写入 N 个字符时,读/写指针都会在文件中向前移动该量。如果您还记得的话,我觉得把它想象成一盘旧磁带会有所帮助。因此,如果您执行以下代码:

fd = open("testfile.txt", "w+")
fd.write("This is a test file.
")
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:UsersjohndoeDesktop    estfile.txt", "r+")

或者最便携的选项是使用os.path.join()

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

您可以在官方 Python 文档中找到有关文件 IO 的更多信息。

解决方案 3:

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

解决方案 4:

您可以在 python 中读取、修改和保存到同一个文件,但实际上您必须替换文件中的全部内容,并在更新文件内容之前调用:

# set the pointer to the beginning of the file in order to rewrite the content
edit_file.seek(0)

我需要一个函数来遍历文件夹的所有子目录并根据某些标准编辑文件的内容,如果它有帮助的话:

new_file_content = ""
for directories, subdirectories, files in os.walk(folder_path):
    for file_name in files:
        file_path = os.path.join(directories, file_name)
        # open file for reading and writing
        with io.open(file_path, "r+", encoding="utf-8") as edit_file:
            for current_line in edit_file:
                if condition in current_line:
                    # update current line
                    current_line = current_line.replace('john', 'jack')
                new_file_content += current_line
            # set the pointer to the beginning of the file in order to rewrite the content
            edit_file.seek(0)
            # delete actual file content
            edit_file.truncate()
            # rewrite updated file content
            edit_file.write(new_file_content)
            # empties new content in order to set for next iteration
            new_file_content = ""
            edit_file.close()
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1344  
  信创产业的蓬勃发展推动着各行业数字化转型加速,数据库迁移作为其中关键一环,面临诸多挑战。信创数据库迁移旨在将传统数据库平稳过渡到信创环境,以满足自主可控、安全可靠的需求。这一过程涉及技术、业务等多方面因素,稍有不慎就可能出现各种问题,影响业务的正常运行。深入探讨信创数据库迁移过程中的常见问题及解决方案,对于保障迁移工作...
2027年信创国产化   54  
  随着信息技术的飞速发展,信创国产化成为了国家战略的重要组成部分。国产化信创产品名录涵盖了众多领域,其在各个关键应用场景中发挥着重要作用。而信创国产化操作系统作为其中的核心环节,具备五大核心优势,为我国信息技术产业的自主可控发展提供了坚实支撑。关键应用场景之办公领域在办公领域,国产化信创产品有着广泛且深入的应用。如今,越...
国产信创系统   50  
  随着信息技术的飞速发展,信创国产化操作系统在政府部门的推广应用具有重要的战略意义。它不仅关乎国家信息安全,更是推动国内信息技术产业自主创新、实现科技自立自强的关键举措。在当前复杂的国际形势下,政府部门积极推广信创国产化操作系统,对于保障国家政务信息的安全稳定运行,提升信息技术的自主可控能力,具有不可替代的重要作用。推广...
信创产品有哪些   37  
  在企业数字化转型的进程中,信创数据库解决方案的选择至关重要。它不仅关乎企业数据的安全存储与管理,更影响着企业业务的稳定运行与未来发展。合适的信创数据库能够助力企业在复杂多变的市场环境中提升竞争力,保障数据主权与安全。然而,面对市场上众多的信创数据库产品和解决方案,企业往往感到困惑,不知如何做出正确的选择。接下来,我们将...
信创电脑   29  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用