我有一个程序,它将通过System.in从外部源接收信息。有两种输入模式:行模式和原始模式。在行模式下,输入只是一系列UTF-8字符串,每个字符串都以换行符结尾。在线路模式下,我会收到通知,说我即将收到N字节的原始数据。此时输入切换到原始模式,并且我会收到N个字节的原始二进制数据,这些数据不是有效的UTF-8字符。在此之后,它返回到行模式。从java中的标准输入读取字符串和原始字节
有没有方法可以轻松地切换阅读字符串和阅读原始数据?我唯一的想法是逐字节地读取一个InputStream字节,并随时转换为字符。有没有什么方法可以将System.in换成多种类型的输入流?我觉得从两个不同的包装纸上读取会导致问题。
(固定)更新:
我试图帕西法尔的建议,但我遇到了一个问题。为了模拟开关输入模式,我修改了测试线束。 (我意识到我拥有的另一个流程最终也需要以这种方式输出。)我不知道问题是由发送端还是接收端引起的。当我在输出模式之间切换时,它似乎没有正确读取字节。而且,它总是出现相同的字节值。这里有一些代码片段:
修复:问题是,显然你不能从OutputStream快速切换到OutputStream。在发送原始字节之前,我添加了1ms睡眠命令,并且问题得以解决!
测试工具:
Process p = processList.get(pubName); //Stored list of started Processes
OutputStream o = p.getOutputStream(); //Returns OutputStream which feeds into stdin
out = new OutputStreamWriter(runPublisher.getOutputStream());
byte[] payload = new byte[25];
out.write("\nPAYLOAD\nRAW\n"); // "RAW\n" signals raw mode
out.write(String.valueOf(payload.length) + "\n");
out.flush();
Thread.sleep(1); //This fixed the problem I was having.
System.out.println(Arrays.toString(payload));
o.write(payload);
o.flush();
客户:
InputStreamReader inReader = new InputStreamReader(System.in);
while(true){
try{
if((chIn = inReader.read())!= -1){
if(chIn == (int)'\n'){
if(rawMode){
if(strIn.equals("ENDRAW"))
rawMode = false;
else{
System.out.println(strIn);
//Exception on next line
int rawSize = Integer.parseInt(strIn);
payload = new byte[rawSize];
int t = System.in.read(payload);
System.out.println("Read " + t + " bytes");
System.out.print(Arrays.toString(payload));
}
}else if(strIn.startsWith("RAW")){
rawMode = true;
}else {
// Do other things
}
strIn = "";
}else
strIn += (char)chIn;
}else
break;
}catch(IOException e){break;}
}
,输出(前要添加休眠语句)是这样的:
测试工具:
[1,1 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
客户:
读取9个字节
[83,72,85,84,68,79,87,78,10,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0]
Exception in thread "main" java.lang.NumberFormatException: For input string: "
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:470)
at java.lang.Integer.parseInt(Integer.java:514)
at myClass.handleCommand(myClass.java:249)
用户如何输入原始字节0x00通过键盘?! –
你能保证在原始字节之前换行吗? – parsifal
@YasserZamani,它不是来自键盘。它由另一个程序控制,并且命令通过stdin传入。 –