我用Java编写多线程服务器。服务器从/到客户端的文件传输。该项目的要求是使用NIO来处理文件。
由于服务器是多线程的,我没有使用SocketChannels进行通信,而不是我使用的是简单的套接字。
为了满足NIO的要求,我被迫使用FileChannels从读/写文件。现在的问题是:它是有意义的转移FileChannel和东西是不是一个信道(如一个简单的socket)之间的文件吗?我一定要切换到SocketChannels?
我问这个,因为我总是看到,像这样的传输总是两个通道之间进行的,所以我有点怀疑了。
它是有意义的一个FileChannel之间传输文件>和东西是不是一个信道(如一个简单的socket)?
是的,它确实。
FileChannel
,Socket
和SocketChannel
是Java语言的抽象通过低级别操作系统的系统调用。我不知道它是如何工作的其他操作系统,但在Linux和(可能是一些其他POSIX兼容的操作系统),它是通过read
/ write
/ sendmsg
/等系统调用来实现。如果您正在使用NIO选择它是最有可能委托给epoll
ing文件描述符。看看EPollSelectorProvider
。
我一定要切换到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
它会给你允许在内核文件传输避免因不必要的文件读写和插座的能力。据我所知这样的零拷贝传输不能在Java中,如果你使用纯Socket
s来完成。