什么是Channel?
Channel即通道的意思,NIO的通道类似于流,但有如下区别:
- 通道可以同时进行读写操作,而流同一时刻只能读或者写
- 通道可以实现异步读写数据,而流只可同步操作
- 通道可以从缓冲区读数据,也可以写数据到缓冲区
BIO中的流是单向的,例如FileInputStream对象只能进行读取数据的操作,而NIO中的通道(Channel)是双向的,既可以读也可以写;
Channel在NIO中是一个接口(public interface Channel extends Closeable),常用的实现类有FileChannel、DatagramChannel、ServerSocketChannel、SocketChannel,SocketChannel相当于BIO中的Socket,ServerSocketChannel相当于ServerSocket;
FileChannel用于文件的读写操作,DatagramChannel用于UDP的数据读写,ServerSocketChannel和SocketChannel用于TCP的数据读写;
Channel需要与缓冲区配合使用
FileChannel常用方法
方法名 | 描述 |
---|---|
public int read(ByteBuffer dst) | 从通道读取数据并放到缓冲区中 |
public int write(ByteBuffer src) | 把缓冲区的数据写到通道中 |
public long transferFrom(ReadableByteChannel src, long position, long count) | 从目标通道中复制数据到当前通道 |
public long transferTo(long position, long count, WritableByteChannel target) | 把数据从当前通道复制给目标通道 |
FileChannel写入数据
复制代码
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
29public class FileChannelWrite { public static void main(String[] args) throws Exception{ String str = "hello 2020"; // 创建一个输出流 FileOutputStream fileOutputStream = new FileOutputStream("d:\test.txt"); // 通过fileOutputStream获取fileChannel FileChannel fileChannel = fileOutputStream.getChannel(); // 创建一个缓冲区byteBuffer ByteBuffer byteBuffer = ByteBuffer.allocate(str.length()); // 将字符串放入缓冲区 byteBuffer.put(str.getBytes()); // 前面是写操作,此时需要将缓冲区的数据写入到fileChannel, // 对于fileChannel来说是读操作,所以此时需要对缓冲区进行反转 byteBuffer.flip(); // 将缓冲区的数据写入fileChannel fileChannel.write(byteBuffer); // 关闭输出流,也可单独关闭fileChannel -> fileChannel.close(); fileOutputStream.close(); } }
FileChannel读取数据
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class FileChannelRead { public static void main(String[] args) throws Exception{ // 创建一个输入流 File file = new File("d:\test.txt"); FileInputStream fileInputStream = new FileInputStream(file); // 通过fileInputStream获取fileChannel FileChannel fileChannel = fileInputStream.getChannel(); // 创建一个缓冲区byteBuffer ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length()); // 将通道中的数据读入到缓冲区 fileChannel.read(byteBuffer); System.out.println(new String(byteBuffer.array())); // 关闭输出流,也可单独关闭fileChannel -> fileChannel.close(); fileInputStream.close(); } }
FileChannle从A文件读取内容并写入到B文件
复制代码
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
31public class FileChannelReadWrite { public static void main(String[] args) throws Exception{ FileInputStream fileInputStream = new FileInputStream("d:\test.txt"); FileChannel inputStreamChannel = fileInputStream.getChannel(); FileOutputStream fileOutputStream = new FileOutputStream("d:\out.txt"); FileChannel outputStreamChannel = fileOutputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while (true) { // 清空buffer byteBuffer.clear(); int read = inputStreamChannel.read(byteBuffer); if(read == -1){ break; } // 将buffer中的数据写入到outputStreamChannel byteBuffer.flip(); outputStreamChannel.write(byteBuffer); } fileInputStream.close(); fileOutputStream.close(); } }
FileChannel使用transferFrom拷贝文件
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class FileChannelTransferFrom { public static void main(String[] args) throws Exception { FileInputStream fileInputStream = new FileInputStream("d:\Koala.jpg"); FileChannel inputStreamChannel = fileInputStream.getChannel(); FileOutputStream fileOutputStream = new FileOutputStream("d:\Koala_bak.jpg"); FileChannel outputStreamChannel = fileOutputStream.getChannel(); // 使用transferFrom进行copy outputStreamChannel.transferFrom(inputStreamChannel, 0, inputStreamChannel.size()); // 关闭流 fileInputStream.close(); fileOutputStream.close(); } }
最后
以上就是端庄菠萝最近收集整理的关于Netty剖析之NIO-Channel的全部内容,更多相关Netty剖析之NIO-Channel内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复