在Node.JS中,我生成了一个子Python进程来管道化。我想通过stdin发送一个UInt8Array。为了通知要读取的缓冲区数据的大小,我之前发送了它的大小。但是它不会在达到指定大小后停止从缓冲区读取实际数据。因此,Python进程不会永远终止。我已经检查了它正确地接受bufferSize并将其转换为整数。在没有size = int(input())
和python.stdin.write(bufferSize.toString() + "n")
并且硬编码缓冲区大小的情况下,它可以正常工作。我不明白为什么它在读取指定的字节数后不结束等待。
// Node.JS
const python_command = command.serializeBinary()
const python = spawn('test/production_tests/py_test_scripts/protocolbuffer/venv/bin/python', ['test/production_tests/py_test_scripts/protocolbuffer/command_handler.py']);
const bufferSize = python_command.byteLength
python.stdin.write(bufferSize.toString() + "n")
python.stdin.write(python_command)
# Python
size = int(input())
data = sys.stdin.buffer.read(size)
简而言之,问题源于先将正常标准置于input()
中,然后再置于sys.stdin.buffer.read
中。我猜前一个与后一个相冲突,使它不能正常工作。
这里有两个潜在问题。首先,node.js和python脚本之间的管道是块缓冲的。在一个块的数据值被填满(取决于系统)或管道被关闭之前,你不会在python端看到任何数据。第二个是在input
和进入stdin的字节流之间有一个解码器。这个解码器可以随心所欲地在流中提前读取。读取sys.stdin.buffer
可能会错过解码器中缓冲的内容。
您可以通过从缓冲区执行所有读取操作来解决第二个问题,如下所示。第一个问题需要在node.js端解决——可能通过关闭它的子进程stdin来解决。您最好将大小写成二进制数,例如uint64。
import struct
import sys
# read size - assuming its coming in as ascii stream
size_buf = []
while True:
c = sys.stdin.buffer.read(1)
if c == b"n":
size = int(b"".join(size_buf))
break
size_buf.append(c)
fmt = "B" # read unsigned char
fmtsize = struct.calcsize(fmt)
buf = [struct.unpack(fmt, sys.stdin.buffer.read(fmtsize))[0] for _ in range(size)]
print(buf)