私はInputStream
をFile
に書き込むために次の方法を使用しています:
private void writeToFile(InputStream stream) throws IOException {
String filePath = "C:\\Test.jpg";
FileChannel outChannel = new FileOutputStream(filePath).getChannel();
ReadableByteChannel inChannel = Channels.newChannel(stream);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(true) {
if(inChannel.read(buffer) == -1) {
break;
}
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
inChannel.close();
outChannel.close();
}
これがNIOを使用する正しい方法かどうか疑問に思っていました。メソッドを読みました FileChannel.transferFrom
、これは3つのパラメータを取ります:
私の場合、src
しかなく、position
とcount
がありません。この方法を使用してファイルを作成する方法はありますか?
また、画像については、InputStream
とNIOからのみ画像を作成するより良い方法はありますか?
どんな情報も私にとって非常に役に立ちます。ここにも同様の質問がありますが、私の場合に適した特定の解決策は見つかりません。
いいえ、それは正しくありません。データを失うリスクがあります。正規のNIOコピーループは次のとおりです。
_while (in.read(buffer) >= 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
_
EOSでの出力のフラッシュを処理する変更されたループ条件と、短い書き込みの可能性を処理するcompact()
ではなくclear(),
の使用に注意してください。
同様に、正規のtransferTo()/transferFrom()
ループは次のとおりです。
_long offset = 0;
long quantum = 1024*1024; // or however much you want to transfer at a time
long count;
while ((count = out.transferFrom(in, offset, quantum)) > 0)
{
offset += count;
}
_
クォンタム全体の転送は保証されていないため、ループで呼び出す必要があります。
Files.copyを使用します
Files.copy(is, Paths.get(filePath));
あなたのバージョンについては
ByteBuffer.allocateDirect
はより高速です-JavaはネイティブI/O操作を直接実行するために最善を尽くします。
クローズは信頼性が低く、最初に失敗した場合、2番目は実行されません。代わりにtry-with-resourcesを使用してください。チャネルもAutoCloseable
です。