如何从Java中的标准输入读取python二进制字符串

时间:2013-11-14 15:29:29

标签: java python protocol-buffers stdin

我有一个使用协议缓冲区的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

2 个答案:

答案 0 :(得分:1)

由于您有二进制数据,因此无法使用readLine()

  1. 不要使用Reader API,您有二进制数据。只需使用BufferedInputStream

  2. 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);

无需以字节

读取它