私は現在、2 つのモジュールを開発段階に持っています。1 つは として出力されOutputStream
、もう 1 つは のみを受け入れますInputStream
。
これら 2 つの部分を接続できるように、どのようOutputStream
に変換するか (その逆ではなく、実際にこの方法を意味します) をご存知ですか?InputStream
ベストアンサー1
リンクやその他のものはたくさんあるようですが、パイプを使用する実際のコードはありません。java.io.PipedInputStream
そしてjava.io.PipedOutputStream
メモリの追加消費がないことです。ByteArrayOutputStream.toByteArray()
は元のバッファのコピーを返すので、メモリ内にあるものはすべて 2 つのコピーを持つことになります。 次に、に書き込むと、InputStream
データのコピーが 3 つあることになります。
使用したコードlambdas
(コメントの @John Manko 氏に感謝):
PipedInputStream in = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(in);
// in a background thread, write the given output stream to the
// PipedOutputStream for consumption
new Thread(() -> {originalOutputStream.writeTo(out);}).start();
@John Manko が指摘したことの 1 つは、特定のケースでは、 OutputStreamの作成を制御できない場合、作成者がOutputStreamオブジェクトを途中でクリーンアップしてしまう可能性があるということです。 を取得している場合はClosedPipeException
、コンストラクターを反転してみてください。
PipedInputStream in = new PipedInputStream(out);
new Thread(() -> {originalOutputStream.writeTo(out);}).start();
以下の例でもコンストラクターを反転できることに注意してください。
Thread
を単に開始するのではなく、を開始するように訂正してくれた @AlexK にも感謝しますRunnable
。
使用するコードtry-with-resources
:
// take the copy of the stream and re-write it to an InputStream
PipedInputStream in = new PipedInputStream();
new Thread(new Runnable() {
public void run () {
// try-with-resources here
// putting the try block outside the Thread will cause the
// PipedOutputStream resource to close before the Runnable finishes
try (final PipedOutputStream out = new PipedOutputStream(in)) {
// write the original OutputStream to the PipedOutputStream
// note that in order for the below method to work, you need
// to ensure that the data has finished writing to the
// ByteArrayOutputStream
originalByteArrayOutputStream.writeTo(out);
}
catch (IOException e) {
// logging and exception handling should go here
}
}
}).start();
私が書いた元のコード:
// take the copy of the stream and re-write it to an InputStream
PipedInputStream in = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(in);
new Thread(new Runnable() {
public void run () {
try {
// write the original OutputStream to the PipedOutputStream
// note that in order for the below method to work, you need
// to ensure that the data has finished writing to the
// ByteArrayOutputStream
originalByteArrayOutputStream.writeTo(out);
}
catch (IOException e) {
// logging and exception handling should go here
}
finally {
// close the PipedOutputStream here because we're done writing data
// once this thread has completed its run
if (out != null) {
// close the PipedOutputStream cleanly
out.close();
}
}
}
}).start();
このコードでは、ファイルに書き込む場合を除き、通常はこれが唯一使用可能な出力ストリームであると想定していますoriginalByteArrayOutputStream
。ByteArrayOutputStream
これの優れた点は、別のスレッドにあるため、並列で動作し、入力ストリームを消費しているものはすべて、古い出力ストリームからもストリーミングされることです。これは、バッファを小さく保つことができ、レイテンシとメモリ使用量が少なくなるため、有益です。
がない場合はByteArrayOutputStream
、 を使用する代わりに、 クラスのメソッドの 1 つ、またはサブクラスで使用可能な他のメソッドの 1 つwriteTo()
を使用する必要があります。write()
java.io.OutputStream