在我的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缓冲区读取数据?
(对不起,英语不好。
答案 0 :(得分:0)
来自维基百科(强调我):
从终端输入永远不会“结束”(除非设备已断开连接),但是在终端中输入多个“文件”很有用,因此键序列被保留以指示输入结束。在UNIX中,键击转换为EOF是由终端驱动程序执行的,因此程序无需将终端与其他输入文件区分开。
无法向您发送期望的EOF
字符。 EOF
实际上不是一个存在的字符。在终端中时,可以按Windows上的键序列 ctrl z 和 ctrl d 在类似UNIX的环境中。它们为终端产生控制字符(在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");