0

我有一个使用协议缓冲区的 python 应用程序,以及一个使用协议缓冲区的 Java 应用程序。我想要做的只是能够将消息(序列化后的二进制字符串)打印到标准输出。为此,我在 Python 应用程序中执行以下操作:

def printMessage(self, protobuf_msg):

数据 = protobuf_msg.SerializeToString()

sys.stdout.write(数据)

sys.stdout.flush()

定义主():

protobuf_msg = create_message()

controller.printMessage(protobuf_msg)

之后,我想通过管道输出这个输出(python pytonApp | java javaApp)并使用 javaApp 获取这些数据并解析它。我尝试了两个选项,使用 Protobuf API 执行此操作:

受保护的 ProtobufMsg receiveMsg() 抛出异常{

ProtobufMsg 消息 = 空;

消息 = protobuf_msg.parseFrom(System.in);

返回消息;

}

我还尝试通过以下方式使用 BufferedInputStream 执行此操作:

受保护的 ProtobufMsg receiveMsg() 抛出异常{

ProtobufMsg 消息 = 空;

字节[] 数据 = receiveFromStd();

message = protobuf_msg.parseFrom(data);

返回消息;

}

公共字节[] receiveFromStd() 抛出异常{

BufferedInputStream 输入 = 新的 BufferedInputStream(System.in);

字节[]输出=新字节[1024];

int i=0;

System.out.println("Entering While");

while((out[i] = (byte)input.read())!= -1){

    i++;

System.out.println("读取一个字节");

}

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

4

2 回答 2

1

你不能使用readLine(),因为你有二进制数据。

  1. 不要使用ReaderAPI,你有二进制数据。只需使用BufferedInputStream.

  2. protobuf 肯定有一个 API 可以直接从流中读取。用那个。不要忘记刷新子节点的输出,否则数据将永远位于 4K 管道缓冲区中:

    sys.stdout.write(data)
    sys.stdout.flush()
    
于 2013-11-14T15:43:38.763 回答
0

我无法评论 Python 方面,但如果它是二进制消息,你可以这样做

    FileInputStream in = new FileInputStream(fileName);

    message = Extension01.Message.parseFrom(in);

或者如果它是一个分隔消息:

    FileInputStream in = new FileInputStream(fileName);

    message = Extension01.Message.parseDelimitedFrom(in);

无需将其作为字节读取

于 2013-11-14T20:53:15.343 回答