2013-11-14 4 views
0

У меня есть приложение python с использованием буферов протоколов и приложение Java с использованием буферов протокола. То, что я хочу сделать, это просто напечатать сообщение (двоичную строку после сериализации) до стандартного вывода. Для этого я сделать следующее в приложении Python:Как читать двоичную строку python из стандартного ввода в Java

четкости printMessage (самость, protobuf_msg):

данных = protobuf_msg.SerializeToString()

sys.stdout.write (данные)

sys.stdout.flush()

защиту Основной():

protobuf_msg = create_message()

controller.printMessage (protobuf_msg)

И после этого, я хочу, чтобы этот выход трубы (питон pytonApp | java javaApp) и получить эти данные с помощью javaApp и проанализировать его. Я попробовал два варианта, делая это с Protobuf API:

защищен ProtobufMsg receiveMsg() бросает исключение {

ProtobufMsg сообщение = NULL;

message = protobuf_msg.parseFrom (System.in);

возвращение сообщения;

}

Я также пытаюсь сделать это с BufferedInputStream следующим образом:

защищен ProtobufMsg receiveMsg() бросает исключение {

ProtobufMsg сообщение = null;

байт [] data = receiveFromStd();

message = protobuf_msg.parseFrom (data);

возвращение сообщения;

}

общественных байты [] receiveFromStd() бросает исключение {

входа BufferedInputStream = новый BufferedInputStream (System.в);

байт [] out = новый байт [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() ...

EDIT: Я решил изменить str ategy и теперь я получаю первый размер пакета, и после этого пакета, так как я использую input.read функции (байт []) ... Сценарий я использую следующий:

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

readLine() требует возврата символа конца строки или «разблокировки». поэтому, возможно, вам также нужно добавить 'sys.stdout.write ('\ n')' – lalli

+0

Подсказка: кнопка '{}' в редакторе Stackoverflow превращает выделенные строки в правильно отступы, выделенный код. –

ответ

0

Вы не можете использовать readLine(), так как у вас есть двоичные данные.

  1. Не используйте API Reader, у вас есть двоичные данные. Просто используйте BufferedInputStream.

  2. У protobuf наверняка есть API для чтения непосредственно из потока. Используйте это. Не забудьте очистить выход ребенка или данные будут сидеть вечно в буфере трубы 4K:

    sys.stdout.write(data) 
    sys.stdout.flush() 
    
+0

Второй не работает, потому что вы получаете только EOF, когда ребенок завершается. Вам действительно нужно заранее знать, сколько байтов читать. У меня сложилось впечатление, что протобуф может это сделать, поэтому первый вызов должен работать, если вы не забудете прикрыть ребенка. –

+0

Спасибо, я пробовал с API protobuf: _protobufMsg.parseFrom (System.in) _; а также я попытался использовать BufferedInputStream: _BufferedInputStream input = new BufferedInputStream (System.in); while ((out [i] = (byte) input.read())! = -1) {i ++; } _. , но в этом случае он остается на input.read() один раз и никогда не читает никакого байта. Благодарим за помощь @AaronDigulla. – user2992697

+0

Я сбросил выход приложения python, и я пробовал с protobuf API и BufferedInputStream и до сих пор не работает ... Но я не уверен, правильно ли использую BufferedInputStream ... – user2992697

0

Я не могу комментировать на стороне Python, но если это бинарное сообщение, которое вы можете сделать

FileInputStream in = new FileInputStream(fileName); 

    message = Extension01.Message.parseFrom(in); 

или, если это разделителями сообщение:

FileInputStream in = new FileInputStream(fileName); 

    message = Extension01.Message.parseDelimitedFrom(in); 

Там нет необходимости читать его в виде байтов

Смежные вопросы