如何在python3中的EOF之前提前读取stdin缓冲区



在我的python代码中,我编写了以下函数来接收来自stdin的自定义二进制包。

def recvPkg():
## The first 4 bytes stands for the remaining package length
Len = int.from_bytes(sys.stdin.buffer.read(4), byteorder='big', signed=True)
## Then read the remaining package
data = json.loads(str(sys.stdin.buffer.read(Len), 'utf-8'))
## do something...
while True:
recvPkg()

然后,在另一个Node.js程序中,我将这个python程序作为子进程生成,并向它发送字节

childProcess = require('child_process').spawn('./python_code.py');
childProcess.stdin.write(someBinaryPackage)

我希望子进程在收到包后从其stdin缓冲区中读取并给出输出。但它不起作用,我认为原因是子进程不会开始读取,除非它的stdin缓冲区接收到一个信号,比如EOF。作为证明,如果我在stdin.write之后关闭childProcess的stdin,python代码将工作并同时接收所有缓冲包。这不是我想要的方式,因为我需要打开childProcess的stdin。那么,node.js有没有其他方法可以向childProcess发送信号,通知从stdin缓冲区读取?

(抱歉英语不好。

来自维基百科(emphasis mine(:

来自终端的输入从未真正"结束"(除非设备断开连接(,但在终端中输入多个"文件"是有用的,因此保留键序列以指示输入结束。在UNIX中,按键到EOF的转换由终端驱动程序执行,因此程序不需要将终端与其他输入文件区分开来。

无法按预期方式发送EOF字符。EOF并不是一个真正存在的角色。当您在终端中时,您可以在Windows上按ctrlz键序列,在类似UNIX的环境中按ctrld键序列。这些为终端生成控制字符(在Windows上为代码26,在UNIX上为代码04(,并由终端读取。终端(读取此代码后(将基本上停止写入程序stdin,并关闭

在Python中,一个文件对象将永远.read()。EOF条件是.read()返回''。在其他一些语言中,这可能是-1或其他条件。

考虑:

>>> my_file = open("file.txt", "r")
>>> my_file.read()
'This is a test file'
>>> my_file.read()
''

这里的最后一个字符不是EOF,那里什么都没有。Python在文件末尾之前都有.read(),不能再使用.read()了。

因为stdin是一种特殊类型的"文件",所以它没有结尾你必须定义这个目的。终端已经将该端定义为控制字符,但这里您不是通过终端将数据传递给stdin,您必须自己管理它。

只是关闭文件

输入[…]从未真正"结束"(除非设备断开连接(

关闭stdin可能是这里最简单的解决方案。stdin是一个无限大的文件,所以一旦你完成了对它的写入,就关闭它

期待你自己的控制角色

另一种选择是定义自己的控制字符。你可以在这里随心所欲。下面的示例使用NULL字节。

蟒蛇
class FileWithEOF:
def __init__(self, file_obj):
self.file = file_obj
self.value = bytes()
def __enter__(self):
return self
def __exit__(self, *args, **kwargs):
pass
def read(self):
while True:
val = self.file.buffer.read(1)
if val == b"x00":
break
self.value += val
return self.value
data = FileWithEOF(sys.stdin).read()
节点
childProcess = require('child_process').spawn('./python_code.py');
childProcess.stdin.write("Some text I want to send.");
childProcess.stdin.write(Buffer.from([00]));

你可能读错了长度

我认为您在Len中捕获的值小于您的文件长度。

蟒蛇
import sys
while True:
length = int(sys.stdin.read(2))
with open("test.txt", "a") as f:
f.write(sys.stdin.read(length))
节点
childProcess = require('child_process').spawn('./test.py');
// Python reads the first 2 characters (`.read(2)`)
childProcess.stdin.write("10"); 
// Python reads 9 characters, but does nothing because it's
// expecting 10. `stdin` is still capable of producing bytes from
// Pythons point of view.
childProcess.stdin.write("123456789");
// Writing the final byte hits 10 characters, and the contents
// are written to `test.txt`.
childProcess.stdin.write("A");

最新更新