在 FileChannel 和 Socket 之间传输文件

Transerring files between FileChannel and Socket

我正在 Java 中编写多线程服务器。服务器传输文件 from/to 个客户端。项目需求是使用NIO处理文件

由于服务器是多线程的,我没有使用 SocketChannels 进行通信,而是使用简单的套接字。

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

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

does it make sense to transfer files between a FileChannel >and something that isn't a channel (like a simple Socket)?

是的,确实如此。

FileChannelSocketSocketChannel 是对低级 OS 系统调用的 Java 语言抽象。我不知道它在其他 OS 上如何工作,但在 Linux 和(可能是其他一些 POSIX 兼容 OSes)上它是通过 read/write/sendmsg/等..系统调用。如果你使用 NIO 选择器,它很可能被委托给 epolling 文件描述符。看看EPollSelectorProvider.

Do I have to switch to SocketChannels?

视情况而定。 NIO 支持零拷贝文件: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/FileChannel.html#transferTo(long,long,java.nio.channels.WritableByteChannel) 。 Linux 通过 sendfile 系统调用支持这一点: http://man7.org/linux/man-pages/man2/sendfile.2.html

它将使您能够允许在内核中传输文件,从而避免从文件到套接字的不必要的读写。据我所知,如果您使用纯 Sockets,则无法在 Java 中完成这种零拷贝传输。