通道的理解
通道是由java.nio.channels包定义的。Channel表示IO源与目标打开的连接。Channel类似于传统的“流”。只不过Channel本身不能直接访问数据,Channel只能与buffer进行交互。
通道的主要实现类
类 | 解析 |
---|---|
FileChannel | 本机IO,用于本地文件传输 |
SocketChannel | 网络IO,使用TCp协议 |
ServerSocketChannel | 网络IO,使用TCP协议 |
DatagramChannel | 网络IO,使用UDP协议 |
实例
使用非直接缓冲区进行文件复制
如果对直接缓冲区没有了解的小伙伴可以去看看这篇文章<<直接缓冲区和非直接缓冲区>>
1 @Test
2 public void test2() throws Exception{
3 FileInputStream fileInputStream = new FileInputStream("src/test/1.png");
4 FileOutputStream fileOutputStream = new FileOutputStream("src/test/2.png");
5
6 // 获取通道
7 FileChannel fileInputStreamChannel= fileInputStream.getChannel();
8 FileChannel fileOutputStreamChannel = fileOutputStream.getChannel();
9
10 // 分配指定大小的缓冲区
11 ByteBuffer buf = ByteBuffer.allocate(1024);
12
13 // 将通道张的数据存入缓冲区
14 while (fileInputStreamChannel.read(buf) != -1){
15 // 切换到读取数据的模式
16 buf.flip();
17 // 将缓冲区中的数据写入通道中
18 fileOutputStreamChannel.write(buf);
19 // 清空缓冲区
20 buf.clear();
21 }
22
23 fileInputStreamChannel.close();
24 fileOutputStreamChannel.close();
25 fileInputStream.close();
26 fileOutputStream.close();
27 }
程序运行后会在相应的文件夹下生成2.png哦!
使用直接缓冲区进行文件的复制
在贴代码之前我们先来看看通道的几种操作模式
模式 | 解释 |
---|---|
StandardOpenOption.READ | 读模式 |
StandardOpenOption.WRITE | 写模式 |
StandardOpenOption.CREATE | 创建模式,如果没有文件就创建文件,如果有文件则覆盖文件 |
StandardOpenOption.NEW_CREATE | 创建模式,如果没有文件就创建文件,如果有文件则报错 |
下面看看代码
1 @Test
2 public void test3() throws Exception{
3 FileChannel inChannel = FileChannel.open(Paths.get("src/test/1.png"), StandardOpenOption.READ);
4 FileChannel outChannel = FileChannel.open(Paths.get("src/test/3.png"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
5
6 // 内存映射文件
7 MappedByteBuffer inMapBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
8 MappedByteBuffer outMapBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
9
10 // 直接对缓冲区进行数据的读写操作
11 byte[] dst = new byte[inMapBuffer.limit()];
12 inMapBuffer.get(dst);
13 outMapBuffer.put(dst);
14
15 inChannel.close();
16 outChannel.close();
17
18 }
另外我们再来看看直接缓存区的简化版的,是通过tranferFrom和tranferTo两个方法进行实现的
1 @Test
2 public void test4() throws tongdaoException{
3 FileChannel inChannel = FileChannel.open(Paths.get("src/test/1.png"), StandardOpenOption.READ);
4 FileChannel outChannel = FileChannel.open(Paths.get("src/test/5.png"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
5
6 // inChannel.transferTo(0, inChannel.size(), outChannel);
7 outChannel.transferFrom(inChannel, 0, inChannel.size());
8
9 inChannel.close();
10 outChannel.close();
11 }