在Python中将文件描述符(管道)转换为文件对象

4

我想使用匿名管道在Linux两个进程之间传递被pickle序列化的对象。我不想使用subprocess模块,而是手动创建必要的管道,然后调用pickle.dumppickle.load函数。然而,这最后两个函数需要一个文件对象。所以,在测试期间,我遇到了以下问题。下面的代码可以正常工作:

import os
r, w = os.pipe()
os.write(w, b"test")
os.read(r, 1024)

但是这段代码在读取操作处停滞不前。
import os
r, w = os.pipe()
fr = os.fdopen(r, "rb")
fw = os.fdopen(w, "wb")
fw.write(b"test")
fr.read()

此外,select.select([r],[],[],0)显示管道为空。我的问题是:在文件对象创建过程中发生了什么,为什么它对管道无效?是否有办法通过这种方式获取文件对象?

1
请在提问 Python 相关问题时始终使用通用的 [python] 标签。 - juanpa.arrivillaga
好的,将来会做! - Ivan
1个回答

2
你遇到了两个问题。首先,os.fdopen 创建的文件对象默认是带缓冲的。你可以将其设置为无缓冲模式。
fr = os.fdopen(r, "rb", buffering=0)
fw = os.fdopen(w, "wb", buffering=0)

或者刷新已经写入的数据:

fw.write(b"test")
fw.flush()

其次,函数fr.read()在没有参数的情况下读取到文件末尾。对于管道来说,这意味着直到管道关闭。你应该传递你想要读取的字节数:

最初的回答:

第二个问题,如果不带参数调用fr.read()函数,则会读取到文件的末尾。对于管道而言,它将一直读取,直到管道关闭。因此,您需要传递您想要读取的字节数。

fr.read(4)
> b'test'

如果你不确定要写入多少数据,请逐步阅读它,每次调用 N 个字节,然后重新组合。最初的回答。

谢谢,这很有道理(而且在内置的“open”文档中,我应该更加关注它:-)) - Ivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接