java - FileChannel 和 Socket 之间传输文件

标签 java file sockets nio filechannel

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

由于服务器是多线程的,因此我没有使用 SocketChannel 进行通信,而是使用简单的 Socket。

为了满足 NIO 要求,我被迫使用 FileChannels 来读取/写入文件。现在的问题是:在 FileChannel 和非 channel 的东西(比如简单的 Socket)之间传输文件是否有意义?我必须切换到 SocketChannels 吗?

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

最佳答案

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

是的,确实如此。

FileChannelSocketSocketChannel 是低级操作系统系统调用的 Java 语言抽象。我不知道它在其他操作系统上如何工作,但在 Linux 和(可能是其他一些兼容 POSIX 的操作系统)上,它是通过 read/write/sendmsg 实现的/etc..系统调用。如果您使用 NIO 选择器,它很可能被委托(delegate)给 epoll 文件描述符。看看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

它将使您能够允许内核内文件传输,避免从文件和套接字进行不必要的读写。 AFAIK 如果您使用普通的 Socket,则无法在 Java 中完成这种零拷贝传输。

关于java - FileChannel 和 Socket 之间传输文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54617758/

相关文章:

java - 为什么我的 SwingWorker 线程在执行完后仍继续运行?

java - 使用屏幕尺寸裁剪图像中心

java - 除了依赖注入(inject)或观察者之外,Java 中单例模式的替代方案

java - 引用数组的一个元素

c - 为什么 “while ( !feof (file) )” 总是错误的?

python - pymongo 问题 : TypeError: document must be an instance of dict, bson.son.SON

php - move_uploaded_file() 无法将文件从 tmp 移动到 dir

node.js - Socket.io 具有多个命名空间?

sockets - Nginx 1.6 + php5-fpm 套接字通信失败

c - 如何使用 UDP_CORK 正确设置 UDP 套接字