System.inを介して外部ソースから情報を受信するプログラムがあります。入力モードには、ラインモードとrawモードの2つがあります。ラインモードでは、入力は単純に一連のUTF-8文字列であり、それぞれが改行文字で終了します。ラインモードのある時点で、Nバイトの生データを受信しようとしているという通知を受け取ります。その時点で、入力はrawモードに切り替わり、有効なUTF-8文字ではないrawバイナリデータを正確にNバイト受信します。この後、ラインモードに戻ります。
文字列の読み取りと生データの読み取りを簡単に切り替える方法はありますか?私の唯一の考えは、InputStreamをバイトごとに読み取り、文字に変換することです。System.inを複数のタイプの入力ストリームでラップする方法はありますか?2つの異なるラッパーから読み取ると問題が発生するように感じます。
(修正済み)更新:
parsifalの提案を試しましたが、問題が発生しています。入力モードの切り替えをシミュレートするために、テストハーネスを変更しました。(私が持っている別のプロセスも、最終的にはこの方法で出力する必要があることに気付きました。)問題の原因が送信側か受信側かはわかりません。出力モードを切り替えると、バイトが正しく読み込まれていないようです。また、表示されるのは常に同じバイト値です。以下にいくつかのコードの抜粋を示します。
修正: 問題は、明らかにOutputStreamWriterからOutputStreamにすばやく切り替えることができないことでした。生のバイトを送信する前に1msのsleepコマンドを追加しましたが、問題は解決しました。
テストハーネス:
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;}
}
そして、出力(Sleepステートメントを追加する前)は次のようになります。
テストハーネス:
[ 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]
クライアント:
25
読み取り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)