我有一个使用协议缓冲区的python应用程序,以及一个使用协议缓冲区的Java应用程序。我想要做的只是能够将消息(序列化后的二进制字符串)打印到标准输出。为此,我在Python应用程序中执行以下操作:
def printMessage(self,protobuf_msg):
data = protobuf_msg.SerializeToString()
sys.stdout.write函数(数据)
sys.stdout.flush()
def main():
protobuf_msg = create_message()
controller.printMessage(protobuf_msg)
之后,我想管道输出(python pytonApp | java javaApp)并使用javaApp获取此数据并解析它。我尝试了两个选项,使用Protobuf API执行此操作:
protected ProtobufMsg receiveMsg()抛出异常{
ProtobufMsg message = null;
message = protobuf_msg.parseFrom(System.in);
返回消息;
}
我也尝试用以下方式对BufferedInputStream执行此操作:
protected ProtobufMsg receiveMsg()抛出异常{
ProtobufMsg message = null;
byte [] data = receiveFromStd();
message = protobuf_msg.parseFrom(data);
返回消息;
}
public byte [] receiveFromStd()抛出异常{
BufferedInputStream input = new BufferedInputStream(System.in);
byte [] out = new byte [1024];
int i=0; System.out.println("Entering While"); while((out[i] = (byte)input.read())!= -1){ i++;
System.out.println(“One byte readed”);
}
byte[] data_out = new byte[i]; for(int l=0; l<data_out.length; l++){ data_out[l]=out[l]; } return data_out;
}
所以很明显我做错了什么但是我无法意识到我做错了什么, 因为它保留在input.read()...
中修改 我决定改变策略,现在我首先得到数据包的大小,然后是数据包,因为我正在使用input.read(byte [])函数... 我正在使用的脚本如下:
FIFO_FILE=/tmp/named_$$ # unique name ($$ is the PID of the bash process running this script)
mkfifo $FIFO_FILE
export FIFO_FILE # export the env variable
ant run & # start a background process that reads the env variable and reads the fifo
cat > $FIFO_FILE # reads the standard input and writes to the fifo
rm $FIFO_FILE
我称之为:python pythonApp.py | ./script
。
答案 0 :(得分:1)
由于您有二进制数据,因此无法使用readLine()
。
不要使用Reader
API,您有二进制数据。只需使用BufferedInputStream
。
protobuf肯定有一个API可以直接从流中读取。用那个。不要忘记刷新子输出,否则数据将永远存在于4K管道缓冲区中:
sys.stdout.write(data)
sys.stdout.flush()
答案 1 :(得分:0)
我无法评论Python方面,但如果它是二进制消息,你可以做
FileInputStream in = new FileInputStream(fileName);
message = Extension01.Message.parseFrom(in);
或者如果是分隔信息:
FileInputStream in = new FileInputStream(fileName);
message = Extension01.Message.parseDelimitedFrom(in);
无需以字节
读取它