6

NIO を使用して ServerSocket 経由で最大 100MB のデータを転送する必要がありますが、どこでも転送を中断したり、転送の状態を維持したりせずにこれを行う方法がわかりません。

私の最初のアイデアは、ファイルのサイズを送信することでした.RAMに一度に収まらないため、その大きなファイルのサイズを送信できないようです。それから、何も受信しないまで転送しないのはなぜだろうと思いましたが、それが問題が発生したときです。

サーバー側のデータを常に書き込んでいても

        FileChannel fc = new FileInputStream(f).getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while(fc.read(buffer) > 0) {
            buffer.flip();
            while(channel.write(buffer) > 0);
            buffer.clear();
        }

しかし、ファイル転送を中断する必要があるため、データを絶えず読み取り、何も利用できないときに中断するのは悪い考えでした。

データの各スライスをオペコードなどを含む新しいパケットとして送信することなく、まだデータが利用可能かどうかをクライアントに伝える方法がわかりませんか、それとも可能ですか?

以下よりもバッファ全体を送信するより良い方法があるかどうかも疑問に思っています

while(channel.write(buffer) > 0);
4

3 に答える 3

5

多分あなたはこれを探しています:

channel.transferFrom(0, fc.size(), fc);
于 2012-05-20T21:11:28.053 に答える
4

バッファを介してチャネルをコピーする正しい方法は次のとおりです。

while (in.read(buffer) >= 0 || buffer.position() > 0)
{
  buffer.flip();
  out.write(buffer);
  buffer.compact();
}

これにより、読み取り長 != 書き込み長、入力の最後にデータが残るなど、すべてのコーナー ケースが処理されます。

ブロッキングモード用です。ノンブロッキング モードのselect()場合、read() または write() がゼロを返す場合は、ループに戻る必要があります。

于 2012-05-21T00:41:32.873 に答える
0

ソケットを開いたままにしておくことができない場合は、回復して続行するメカニズムをプロトコルに組み込む方法はありません。予想されるバイト数をクライアントに伝えることに関しては、を使用してメモリに読み込まずにファイルのサイズを見つけることができますFile.length

于 2012-05-20T22:05:40.437 に答える