csl*_*csl 7 c python file-io python-2.7
关于在追加模式下打开文件然后尝试寻找文件的开头,我遇到了这种奇怪的行为.
代码应该是不言自明的:在第二次打开时,我希望能够将一个字符串写入文件的开头,然后f.tell()
返回5(在文件开头写入的字节数).
问题是,在Python 2.6.6和2.7.6中,最终的断言触发,但令人惊讶的是,它在Python 3.3.2中有效.
# Create new file, write after the 100th byte.
f = open("test", "w+b")
f.seek(100, 0)
f.write(b"end")
assert f.tell() == 100 + len("end")
f.close()
# Open file for writing without overwriting, attempt to write at start of file
# of the file, but doesn't.
f = open("test", "a+b")
f.seek(0, 0)
f.write(b"start")
assert f.tell() == len("start")
f.close()
Run Code Online (Sandbox Code Playgroud)
所以我做了一个相同的C程序.它实际上表现得像Python 2.x版本:
#include <stdio.h>
int main() {
FILE *f = fopen("tt", "w+b");
fseek(f, 100, 0);
fwrite("x", 1, 1, f);
fclose(f);
f = fopen("tt", "a+b");
fseek(f, 0, 0);
fwrite("y", 1, 1, f);
printf("%ld\n", ftell(f));
fclose(f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这打印102
,我认为这是规范的(我也看过strace -eopen,close,lseek
输出,但不是更聪明).
所以我的问题是:我没有什么样的令人尴尬的基本知识?
为什么Python 3的行为有所不同?
顺便说一下,我在Linux上.
Mar*_*ers 10
该行为是您的操作系统强制执行的行为.
Python 2 open()
调用实际上是以与C
代码相同的方式打开文件,稍微包装一下.两者都要求操作系统以给定模式打开文件.然后,您的操作系统明确限制您可以寻求的位置; 你是不是允许寻求阅读或覆盖在那里你打开文件之前的数据.
在Python 3中,I/O已经过大修,新的文件处理代码不会直接将模式传递给操作系统,从而使您不受该限制的约束.您可以使用该io.open()
函数在Python 2中执行相同的操作.
该open()
函数文档肯定会警告你某些操作系统的行为,你甚至不能用seek
使用时a
:
[...]
'a'
附加(在某些Unix系统上意味着所有写入都附加到文件的末尾,而不管当前的搜索位置如何).
在Linux上,open()
手册页明确指出了这种行为:
O_APPEND
该文件以追加模式打开.在每个write(2)
文件之前,文件偏移量位于文件的末尾,就像使用lseek(2)
.
例如,当尝试写入时,文件位置被移动到文件的末尾; 你只被允许追加.
我希望找到一个以这种方式运行的操作系统列表; 它看起来像Microsoft Windows做类似的事情.在.NET FileMode
枚举文档状态:
Append
[...]尝试在文件结束之前寻找某个位置会抛出IOException
异常,并且任何读取尝试都会失败并抛出NotSupportedException
异常.
在任何情况下,如果您要同时写入和读取文件(不仅仅是追加),而不是在打开时截断文件,请使用该'r+'
模式.这将打开文件进行读写.您可以通过寻求到达来追加,但同时您可以自由地寻找文件中的任何一点.
归档时间: |
|
查看次数: |
2598 次 |
最近记录: |