Javaでファイルコンバーター用の小さなGUIをプログラミングしています。ファイル コンバーターは、現在の進行状況を stdout に書き込みます。次のようになります。
Flow_1.wav: 28% complete, ratio=0,447
これを進行状況バーで説明したかったので、プロセスの stdout を次のように読んでいます。
ProcessBuilder builder = new ProcessBuilder("...");
builder.redirectErrorStream(true);
Process proc = builder.start();
InputStream stream = proc.getInputStream();
byte[] b = new byte[32];
int length;
while (true) {
length = stream.read(b);
if (length < 0) break;
// processing data
}
問題は、選択したバイト配列サイズに関係なく、ストリームが 4 KB のチャンクで読み取られることです。したがって、私のコードは実行されるまで実行されlength = stream.read(b);
、その後かなりの時間ブロックされます。プロセスが 4 KB の出力データを生成すると、私のプログラムはこのチャンクを取得し、32 バイトのスライスで処理します。そして、次の 4 KB を再び待ちます。
私はJavaに次のような小さなバッファを強制的に使用させようとしました:
BufferedInputStream stream = new BufferedInputStream(proc.getInputStream(), 32);
またはこれ:
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()), 32);
しかし、どちらも何も変わりませんでした。
次に、これを見つけました:プロセスソース(87行目あたり)
Process クラスは、プロセスの stdout をファイルにパイプするような方法で実装されているようです。つまり、proc.getInputStream();
実際に行うことは、ストリームをファイルに返すことです。そして、このファイルは4KBのバッファで書かれているようです。
この状況の回避策を知っている人はいますか?プロセスの出力をすぐに取得したいだけです。
EDIT : Ian Roberts が示唆したように、コンバーターの出力を stderr ストリームにパイプしようとしました。このストリームはBufferedInputStream
. それでも4kチャンク。
もう 1 つの興味深い点は、実際には正確に 4096 バイトではなく、約 5 バイト多いことです。FileInputStream
それ自体がネイティブにバッファリングされているのではないかと心配しています。