通道(Channel),用于源节点和目标节点的连接。在Java NIO中负责数据的传输。Channel本身不存储数据,所以传输时还需要缓冲区配合。
更多缓冲区的内容,请参考 NIO的缓冲区
利用通道完成文件复制(非直接缓冲区)
可以拷贝超过2G的文件。关于大文件的拷贝,后面再写文章。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| try (FileInputStream fis = new FileInputStream("/infile"); FileOutputStream fos = new FileOutputStream("/outfile");
FileChannel inChannel = fis.getChannel(); FileChannel outChannel = fos.getChannel() ) { ByteBuffer buffer = ByteBuffer.allocate(10240);
while (inChannel.read(buffer) != -1) { buffer.flip(); outChannel.write(buffer); buffer.clear(); } } catch (IOException e) { e.printStackTrace(); }
|
使用直接缓冲区完成文件复制
文件大小不能超过2G。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| try (FileChannel inChannel = FileChannel.open(Paths.get("/infile"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("/outfile"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE)) {
MappedByteBuffer inMappedByteBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); MappedByteBuffer outMappedByteBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
byte[] bytes = new byte[inMappedByteBuffer.limit()]; inMappedByteBuffer.get(bytes); outMappedByteBuffer.put(bytes); } catch (IOException e) { e.printStackTrace(); }
|
通道之间的数据传输(直接缓冲区)
文件大小不能超过2G。
1 2 3 4 5 6 7 8 9 10 11 12
|
try (FileChannel inChannel = FileChannel.open(Paths.get("/Users/simon/Documents/largefile.tar"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("/Users/simon/Documents/largefile.tar.copy"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE)) {
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (IOException e) { e.printStackTrace(); }
|
分散和聚集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| ByteBuffer[] bufs = new ByteBuffer[0]; try (RandomAccessFile raf1 = new RandomAccessFile("/infile", "rw");
FileChannel raf1Channel = raf1.getChannel()) {
ByteBuffer buf1 = ByteBuffer.allocate(100); ByteBuffer buf2 = ByteBuffer.allocate(1024); bufs = new ByteBuffer[]{buf1, buf2};
raf1Channel.read(bufs);
for (ByteBuffer buf : bufs) { buf.flip(); } } catch (IOException e) { e.printStackTrace(); }
System.out.println(new String(bufs[0].array(), 0, bufs[0].limit())); System.out.println("---"); System.out.println(new String(bufs[1].array(), 0, bufs[1].limit()));
try (RandomAccessFile raf2 = new RandomAccessFile("/outfile", "rw"); FileChannel raf2Channel = raf2.getChannel()) {
raf2Channel.write(bufs); } catch (IOException e) { e.printStackTrace(); }
|