Java 在FileChannel和Socket之间传输文件

Java 在FileChannel和Socket之间传输文件,java,file,sockets,nio,filechannel,Java,File,Sockets,Nio,Filechannel,我正在用Java编写一个多线程服务器。服务器将文件从客户端传输到客户端。该项目的一个要求是使用NIO来处理文件 因为服务器是多线程的,所以我没有使用SocketChannels进行通信,而是使用简单的套接字 为了满足NIO的要求,我不得不使用FileChannel来读取/写入文件。现在的问题是:在文件通道和非通道(如简单套接字)之间传输文件有意义吗?我必须换成袜子通道吗 我问这个是因为我一直看到像这样的传输总是在两个频道之间进行,所以我对此有点怀疑 在FileChannel>和非通道(如简单套接

我正在用Java编写一个多线程服务器。服务器将文件从客户端传输到客户端。该项目的一个要求是使用NIO来处理文件

因为服务器是多线程的,所以我没有使用SocketChannels进行通信,而是使用简单的套接字

为了满足NIO的要求,我不得不使用FileChannel来读取/写入文件。现在的问题是:在文件通道和非通道(如简单套接字)之间传输文件有意义吗?我必须换成袜子通道吗

我问这个是因为我一直看到像这样的传输总是在两个频道之间进行,所以我对此有点怀疑

在FileChannel>和非通道(如简单套接字)之间传输文件有意义吗

是的

FileChannel
Socket
SocketChannel
都是底层操作系统系统调用上的Java语言抽象。我不知道它在其他操作系统上是如何工作的,但在Linux和(可能是其他一些兼容POSIX的操作系统)上,它是通过
read
/
write
/
sendmsg
/等实现的。。系统调用。如果您使用的是NIO选择器,它很可能被委托给
epoll
ing文件描述符。查看
EPollSelectorProvider

我必须换成袜子通道吗

视情况而定。NIO支持零拷贝文件:。Linux通过
sendfile
syscall支持这一点:


它将使您能够允许内核内的文件传输,避免不必要的从文件到套接字的读写。如果您使用普通的
Socket
s.

,那么这种零拷贝传输在Java中是无法实现的。因此,使用Socket,我无法利用通道之间的零拷贝,理论上,这比将数据从FileChannel读取到用户空间,然后将其写入套接字更有效。正如我在op中所说的,现在我使用的是简单的阻塞套接字。我想知道在阻塞模式下切换到ServerSocketChannels和SocketChannels是否有意义,就像我在使用简单的套接字,而不使用NIO选择器一样。@PoriPiriPuri如果您想通过
DirectBuffer
s将数据从堆中传输出去,几乎不给GC施加任何压力,这是有意义的
OutputStream
对定义在堆上的
字节[]
进行操作。所以,如果您从
FileChannel
读取数据到直接缓冲区,并希望传输到套接字的
OutputStream
,则必须执行不必要的复制。无论如何,如果您不必加密/压缩或操作用户空间中的数据,那么在内核中传输应该会更有效。