PyPy文件附加模式

Ale*_*ich 7 python pypy

我有这样的代码:

f1 = open('file1', 'a')
f2 = open('file1', 'a')

f1.write('Test line 1\n')
f2.write('Test line 2\n')
f1.write('Test line 3\n')
f2.write('Test line 4\n')
Run Code Online (Sandbox Code Playgroud)

当使用标准Python 2.7解释器运行此代码时,该文件包含预期的四行.但是,当我在PyPy下运行此代码时,该文件只包含两行.

有人可以解释Python和PyPy在附加模式下处理文件时的区别吗?

更新:PyPy 2.3中不存在该问题.

max*_*lis 3

不同行为的原因是文件 I/O 操作的不同实现。

CPython在 之上实现fopen其文件 I/O ,fread并且fwritestdio.h流中运行并使用FILE *流。

同时,PyPy在 POSIX 之上实现open文件 I/O ,writeread运行并使用int文件描述符。

比较这两个 C 语言程序:

#include <stdio.h>

int main() {
    FILE *a = fopen("file1", "a");
    FILE *b = fopen("file1", "a");

    fwrite("Test line 1\n", 12, 1, a);
    fflush(a);
    fwrite("Test line 2\n", 12, 1, b);
    fflush(b);
    fwrite("Test line 3\n", 12, 1, a);
    fflush(a);
    fwrite("Test line 4\n", 12, 1, b);

    fclose(a);
    fclose(b);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

#include <fcntl.h>
#include <unistd.h>

int main() {
    int a = open("file1", O_CREAT | O_WRONLY | O_APPEND);
    int b = open("file1", O_CREAT | O_WRONLY | O_APPEND);

    write(a, "Test line 1\n", 12);
    write(b, "Test line 2\n", 12);
    write(a, "Test line 3\n", 12);
    write(b, "Test line 4\n", 12);

    close(a);
    close(b);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有关 和 之间差异的更多信息,open您可以在这个问题fopen的答案中找到。

更新

在进一步检查 PyPy 代码库之后,在我看来,由于某种原因它不使用O_APPEND标志O_WRONLY | O_CREAT,而是用于“a”模式。因此,这是 PyPy 中每次调用后都需要seek到达文件末尾的真正原因write,正如 JF Sebastian 在另一个答案中提到的那样。我想应该在 PyPy bugtracker 上创建一个 bug,因为O_APPENDflag 在 Windows 和 Unix 上都可用。所以,PyPy 现在所做的看起来像:

#include <fcntl.h>
#include <unistd.h>

int main() {
    int a = open("file1", O_CREAT | O_WRONLY);
    int b = open("file1", O_CREAT | O_WRONLY);

    write(a, "Test line 1\n", 12);
    write(b, "Test line 2\n", 12);
    write(a, "Test line 3\n", 12);
    write(b, "Test line 4\n", 12);

    close(a);
    close(b);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果没有 O_APPEND 标志,它应该重现 PyPy 行为。