Transerring файлы между FileChannel и Socket - PullRequest
0 голосов
/ 10 февраля 2019

Я пишу многопоточный сервер на Java.Сервер передает файлы от / к клиентам.Требование проекта - использовать NIO для обработки файлов.

Поскольку сервер многопоточный, я не использую SocketChannels для связи, вместо этого я использую простые сокеты.

Длясоответствовать требованиям NIO, я вынужден использовать FileChannels для чтения / записи в файлы.Теперь возникает вопрос: имеет ли смысл передавать файлы между FileChannel и чем-то, что не является каналом (например, простым Socket)?Нужно ли переключаться на SocketChannels?

Я спрашиваю об этом, потому что я всегда видел, что подобные передачи всегда делаются между двумя каналами, поэтому я немного сомневался в этом.

1 Ответ

0 голосов
/ 10 февраля 2019

имеет ли смысл передавать файлы между FileChannel> и чем-то, что не является каналом (например, простой Socket)?

Да, это так.

FileChannel, Socket и SocketChannel - абстракция языка Java над системными вызовами ОС низкого уровня.Я не знаю, как это работает в других ОС, но в Linux и (возможно, в некоторых других POSIX-совместимых ОС) это реализовано с помощью системных вызовов read / write / sendmsg / etc ...Если вы используете селекторы NIO, он, скорее всего, делегирован в epoll дескриптор файла.Взгляните на 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 syscall: http://man7.org/linux/man-pages/man2/sendfile.2.html

Это даст вам возможность разрешить передачу файлов в ядре, избегая ненужных операций чтения-записи из файла и в сокет.AFAIK, такая передача нулевой копии не может быть сделана в Java, если вы используете обычный Socket s.

...