在Java中复制文件通道

问题描述 投票:0回答:1

我们可以打开任意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:我想重复的原因是,我想将数据从一个文件同时发送给多个SocketChannels。因此,它似乎是合理的有一个单独的FileChannel转移到一个单一的SocketChannel

java file io jvm
1个回答
2
投票

Java有重复FileChannels没有公共API。

然而,没有必要重复FileChannel的同时写入多个SocketChannels。

  1. FileChannel.transferTo可以同时在多个线程中(至少在类似Unix的系统)一起使用。正如Javadoc中说,这种方法不会修改通道的位置。
  2. FileChannel.read(ByteBuffer, long)也可以在Unix上同时使用。在Windows中,这个方法保持通道的位置锁定。
  3. 另外,它可以创建相同FileChannel使用FileChannel.map的多个字节缓冲区的意见。这些MappedByteBuffers可以同时使用。

如果你仍然想从Java(虽然我不建议这样做)调用dup,你可以使用反射滥用私有API:

  • int sun.nio.fs.UnixNativeDispatcher.dup(int fd)是在Unix dup直接Java包装;
  • long sun.nio.ch.FileDispatcherImpl.duplicateHandle(long handle)是Java包装在Windows DuplicateHandle
© www.soinside.com 2019 - 2024. All rights reserved.