加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在Windows中的Python文件上混合read()和write()

发布时间:2020-12-14 02:18:09 所属栏目:Windows 来源:网络整理
导读:在 Windows中以r(或r b)权限打开的文件上紧跟read()之后的write()似乎不会更新该文件. 假设当前目录中有一个文件testfile.txt,其中包含以下内容: This is a test file. 我执行以下代码: with open("testfile.txt","r+b") as fd: print fd.read(4) fd.write
在 Windows中以r(或r b)权限打开的文件上紧跟read()之后的write()似乎不会更新该文件.

假设当前目录中有一个文件testfile.txt,其中包含以下内容:

This is a test file.

我执行以下代码:

with open("testfile.txt","r+b") as fd:
    print fd.read(4)
    fd.write("----")

我希望代码打印出来并将文件内容更新为:

This----a test file.

这在至少Linux上运行良好.但是,当我在Windows上运行它时,消息显示正确,但文件没有被更改 – 就像write()被忽略.如果我在文件句柄上调用tell(),它会显示位置已更新(在write()之前是4,之后是8),但是没有更改文件.

但是,如果我在write()行之前放置一个显式的fd.seek(4),那么一切都按照我的预期运行.

有人知道Windows下这种行为的原因吗?

作为参考,我在Windows 7上使用带有NTFS分区的Python 2.7.3.

编辑

在回应评论时,我尝试了r b和rb – official Python docs似乎暗示前者是规范的.

我在各个地方调用fd.flush(),并在read()和write()之间放置一个,如下所示:

with open("testfile.txt","r+b") as fd:
    print fd.read(4)
    fd.flush()
    fd.write("----")

…产生以下有趣的错误:

IOError: [Errno 0] Error

编辑2

间接地,添加flush()有帮助,因为它引导我this post描述类似的问题.如果其中一个评论者是正确的,那么它就是底层Windows C库中的一个错误.

解决方法

Python的文件操作应该遵循libc约定,因为它在内部使用C文件IO函数实现.

引自fopen man page或fopen page in cplusplus

For files open for appending (those which include a “+” sign),on
which both input and output operations are allowed,the stream should
be flushed (fflush) or repositioned (fseek,fsetpos,rewind) between
either a writing operation followed by a reading operation or a
reading operation which did not reach the end-of-file followed by a
writing operation.

总而言之,如果你需要在写入后读取文件,你需要刷新缓冲区,读取后的写操作应该以fseek开头,如fd.seek(0,os.SEEK_CUR)

所以只需将您的代码段更改为

with open("test1.txt","r+b") as fd:
    print fd.read(4)
    fd.seek(0,os.SEEK_CUR)
    fd.write("----")

该行为与类似的C程序的行为方式一致

#include <cstdio>
int main()
{   
    char  buffer[5] = {0};
    FILE *fp = fopen("D:Temptest1.txt","rb+");
    fread(buffer,sizeof(char),4,fp);
    printf("%sn",buffer);
    /*without fseek,file would not be updated*/
    fseek(fp,SEEK_CUR); 
    fwrite("----",fp);
    fclose(fp);
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读