简体   繁体   English

在 FileChannel 和 Socket 之间传输文件

[英]Transerring files between FileChannel and Socket

I'm writing a multithreaded server in Java.我正在用 Java 编写多线程服务器。 The server transfers files from/to clients.服务器从/向客户端传输文件。 A requirement of the project is to use NIO to handle files.项目的一个需求是使用NIO来处理文件。

Since the server is multithreaded, I'm not using SocketChannels for the communication, instead I'm using simple Sockets.由于服务器是多线程的,我没有使用 SocketChannels 进行通信,而是使用简单的 Sockets。

To meet the NIO requirement, I'm forced to use FileChannels to read from / write to files.为了满足 NIO 要求,我不得不使用 FileChannels 来读取/写入文件。 Now the question is: does it make sense to transfer files between a FileChannel and something that isn't a channel (like a simple Socket)?现在的问题是:在 FileChannel 和不是通道的东西(如简单的 Socket)之间传输文件是否有意义? Do I have to switch to SocketChannels?我必须切换到 SocketChannels 吗?

I'm asking this because I've always seen that transfers like these are always made between two channels, so I was a little dubious about it.我问这个是因为我一直看到像这样的转移总是在两个渠道之间进行,所以我对此有点怀疑。

does it make sense to transfer files between a FileChannel >and something that isn't a channel (like a simple Socket)?在 FileChannel > 和不是通道的东西(如简单的 Socket)之间传输文件有意义吗?

Yes, it does.是的,它确实。

FileChannel , Socket and SocketChannel are Java language abstraction over low level OS syscalls. FileChannelSocketSocketChannel是对底层操作系统系统调用的 Java 语言抽象。 I don't know how it works on other OS, but on Linux and (probably some other POSIX compliant OSes) it is implemented through read / write / sendmsg /etc.. syscalls.我不知道它在其他操作系统上是如何工作的,但在 Linux 和(可能是其他一些符合 POSIX 的操作系统)上它是通过read / write / sendmsg /etc 实现的。系统调用。 If you are using NIO selectors it is mostly likely delegated to epoll ing file descriptor.如果您使用 NIO 选择器,它很可能委托给epoll ing 文件描述符。 Take a look at EPollSelectorProvider .看看EPollSelectorProvider

Do I have to switch to SocketChannels?我必须切换到 SocketChannels 吗?

Depends.要看。 NIO has support of zero-copy file: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/FileChannel.html#transferTo(long,long,java.nio.channels.WritableByteChannel) . 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 does support this through sendfile syscall: http://man7.org/linux/man-pages/man2/sendfile.2.html Linux 确实通过sendfile系统调用支持这一点: http : //man7.org/linux/man-pages/man2/sendfile.2.html

It would give you the ability to allow in-kernel file transferring avoiding unnecessary read-write from file and to socket.它将使您能够允许内核文件传输,避免从文件和套接字进行不必要的读写。 AFAIK such zero-copy transferring cannot be done in Java if you use plain Socket s. AFAIK 如果您使用普通的Socket s,则无法在 Java 中完成这种零拷贝传输。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM