Дублирование файлового канала в Java - PullRequest
0 голосов
/ 09 февраля 2019

Мы можем открыть канал так же просто, как Files.newByteChannel(path), и это будет работать нормально.Проблема в том, что если я хочу открыть более одного канала:

Channel chan1 = Files.newByteChannel(path);
Channel chan2 = Files.newByteChannel(path);

Пример выше не работает в целом.Рассмотрим обстоятельства:

Channel chan1 = Files.newByteChannel(path); //OK
//Some other process moved path and created an new file with the path
Channel chan2 = Files.newByteChannel(path); //Damn!

Происходит состояние гонки.В Linux у нас есть dup -подобные системные вызовы, а также fcntl(F_DUPFD, int)

int fd == open(path);
int duplicated = fcntl(fd, F_DUPFD, fd);

, и это должно работать.

Есть лиспособ сделать это в Java и избежать написания JNI функции?

UPD: причина, по которой я хочу дубликат, заключается в том, что я хочу передавать данные из одного файла в несколько SocketChannel одновременно.Поэтому кажется разумным иметь отдельный FileChannel для перевода на один SocketChannel.

1 Ответ

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

В Java нет открытого API для дублирования FileChannels.

Однако нет необходимости дублировать FileChannel для одновременной записи в несколько SocketChannel.

  1. FileChannel.transferTo может использоваться одновременно в нескольких потоках (по крайней мере, в Unix-подобных системах).Как говорит Javadoc, этот метод не изменяет положение канала.
  2. FileChannel.read(ByteBuffer, long) может также использоваться одновременно в Unix.В Windows этот метод удерживает блокировку положения канала.
  3. В качестве альтернативы возможно создание нескольких представлений ByteBuffer одного и того же FileChannel с использованием FileChannel.map.Эти MappedByteBuffers могут использоваться одновременно.

Если вы все еще хотите вызывать dup из Java (хотя я бы не рекомендовал это делать), вы можете злоупотреблять частным API, используя Reflection:

  • int sun.nio.fs.UnixNativeDispatcher.dup(int fd) - прямая оболочка Java для dup в Unix;
  • long sun.nio.ch.FileDispatcherImpl.duplicateHandle(long handle) - оболочка Java для DuplicateHandle в Windows.
...