在 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)?
是的,确实如此。
FileChannel
、Socket
和 SocketChannel
是对低级 OS 系统调用的 Java 语言抽象。我不知道它在其他 OS 上如何工作,但在 Linux 和(可能是其他一些 POSIX 兼容 OSes)上它是通过 read
/write
/sendmsg
/等..系统调用。如果你使用 NIO 选择器,它很可能被委托给 epoll
ing 文件描述符。看看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
它将使您能够允许在内核中传输文件,从而避免从文件到套接字的不必要的读写。据我所知,如果您使用纯 Socket
s,则无法在 Java 中完成这种零拷贝传输。
我正在 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)?
是的,确实如此。
FileChannel
、Socket
和 SocketChannel
是对低级 OS 系统调用的 Java 语言抽象。我不知道它在其他 OS 上如何工作,但在 Linux 和(可能是其他一些 POSIX 兼容 OSes)上它是通过 read
/write
/sendmsg
/等..系统调用。如果你使用 NIO 选择器,它很可能被委托给 epoll
ing 文件描述符。看看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
它将使您能够允许在内核中传输文件,从而避免从文件到套接字的不必要的读写。据我所知,如果您使用纯 Socket
s,则无法在 Java 中完成这种零拷贝传输。