InputStream からの時間指定読み取りの可能性
課題は、in.read() と同じ結果を返すmaybeRead というメソッドの設計にあります。指定されたタイムアウト内にデータが利用可能かどうか。具体的には、指定されたタイムアウト内にデータが利用できない場合、maybeRead は -2 を返します。
最初は、InputStream を Reader または InterruptibleChannel でラップすることで解決策が得られるように見えますが、どちらも InputStream メソッドのみを通過します。さらに、このプロセス中にスレッドが生成されないようにすることが重要です。
in.available() は常に 0 を返すと考えられていますが、ドキュメントでは、ブロックせずに読み取り可能なバイトの推定値が提供されることが明らかになりました。この推定は過小評価されている可能性がありますが、新しい到着を考慮して次の呼び出しに追いつきます。
ただし、InputStream のサブクラスは、available() の独自の実装を処理し、具体的な実装はそれをオーバーライドして意味のある値を与えます。したがって、単に is.available() を使用するだけでは十分ではありません。
ノンブロッキングでタイムアウトのない読み取りの場合は、次の解決策を検討してください。
byte[] inputData = new byte[1024]; int result = is.read(inputData, 0, is.available()); // -1 for EOF with no data read.
または
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, Charset.forName("ISO-8859-1")),1024); // ... // inside some iteration / processing logic: if (br.ready()) { int readCount = br.read(inputData, bufferOffset, inputData.length-bufferOffset); }
タイムアウト内でバッファを最大化するより複雑なソリューションについては、以下を利用します。メソッド:
public static int readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis) throws IOException { int bufferOffset = 0; long maxTimeMillis = System.currentTimeMillis() + timeoutMillis; while (System.currentTimeMillis() < maxTimeMillis && bufferOffset < b.length) { int readLength = java.lang.Math.min(is.available(),b.length-bufferOffset); int readResult = is.read(b, bufferOffset, readLength); if (readResult == -1) break; bufferOffset += readResult; } return bufferOffset; }
そして次のように使用します:
byte[] inputData = new byte[1024]; int readCount = readInputStreamWithTimeout(System.in, inputData, 6000); // 6 second timeout // readCount indicates bytes read; -1 for EOF with no data read.
以上がスレッド化せずに、InputStream からの時間指定読み取りを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。