Java - 通过频道传输大文件 - NIO

Ruu*_*kis 6 java nio

我必须使用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();
        }
Run Code Online (Sandbox Code Playgroud)

但是因为文件传输必须中断一段时间不断地读取数据并且在没有任何可用的情况下断开是不好的主意.

我无法弄清楚我怎么可能告诉客户端是否仍有数据可用而不必将每个数据片作为带有操作码等的新数据包发送,或者甚至可能?

我也想知道是否有更好的方式发送整个缓冲区而不是下面

while(channel.write(buffer) > 0);
Run Code Online (Sandbox Code Playgroud)

Hak*_*rce 5

也许你正在寻找这个:

channel.transferFrom(0, fc.size(), fc);
Run Code Online (Sandbox Code Playgroud)


use*_*421 4

通过缓冲区复制通道的正确方法如下:

while (in.read(buffer) >= 0 || buffer.position() > 0)
{
  buffer.flip();
  out.write(buffer);
  buffer.compact();
}
Run Code Online (Sandbox Code Playgroud)

这可以处理所有极端情况,包括读取长度!=写入长度以及在输入末尾留下数据。

注意,这是针对阻塞模式的。如果处于非阻塞模式,select()如果 read() 或 write() 返回零,则应该返回循环。