在 Windows 中的 Python 文件上混合使用 read() 和 write() [英] Mixing read() and write() on Python files in Windows

查看:16
本文介绍了在 Windows 中的 Python 文件上混合使用 read() 和 write()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 r+(或 r+b) Windows 中的权限不会更新文件.

It appears that a write() immediately following a read() on a file opened with r+ (or r+b) permissions in Windows doesn't update the file.

假设当前目录下有一个文件testfile.txt,内容如下:

Assume there is a file testfile.txt in the current directory with the following contents:

This is a test file.

我执行以下代码:

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

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

I would expect the code to print This and update the file contents to this:

This----a test file.

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

This works fine on at least Linux. However, when I run it on Windows then the message is displayed correctly, but the file isn't altered - it's like the write() is being ignored. If I call tell() on the filehandle it shows that the position has been updated (it's 4 before the write() and 8 afterwards), but no change to the file.

但是,如果我在 write() 行之前放置一个显式的 fd.seek(4) ,那么一切都会如我所愿.

However, if I put an explicit fd.seek(4) just before the write() line then everything works as I'd expect.

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

Does anybody know the reason for this behaviour under Windows?

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

For reference I'm using Python 2.7.3 on Windows 7 with an NTFS partition.

编辑

为了回应评论,我尝试了 r+brb+ - 官方 Python 文档 似乎暗示前者是规范的.

In response to comments, I tried both r+b and rb+ - the official Python docs seem to imply the former is canonical.

我在不同的地方调用了 fd.flush(),并在 read()write() 之间放置了一个像这样:

I put calls to fd.flush() in various places, and placing one between the read() and the write() like this:

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

... 产生以下有趣的错误:

... yields the following interesting error:

IOError: [Errno 0] Error

编辑 2

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

Indirectly that addition of a flush() helped because it lead me to this post describing a similar problem. If one of the commenters on it is correct, it's a bug in the underlying Windows C library.

推荐答案

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

Python's file operation should follow the libc convention as internally its implemented using C file IO functions.

引用自 fopen 手册页在cplusplus中打开页面

对于为追加而打开的文件(包含+"号的文件),在允许输入和输出操作,流应该被刷新 (fflush) 或重新定位 (fseek, fsetpos, rewind)要么是写操作,然后是读操作,要么是未到达文件末尾的读取操作后跟写操作.

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.

SO 总结一下,如果你需要在写入后读取文件,你需要fflush缓冲区,并且读取后的写入操作应该在fseek之前,如 fd.seek(0, os.SEEK_CUR)

SO to summarize, if you need to read a file after writing, you need to fflush the buffer and a write operation after read should be preceded by a fseek, as fd.seek(0, os.SEEK_CUR)

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

So just change your code snippet to

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

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

The behavior is consistent with how a similar C program would behave

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

这篇关于在 Windows 中的 Python 文件上混合使用 read() 和 write()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆