我是靠谱客的博主 端庄菠萝,这篇文章主要介绍Netty剖析之NIO-Channel,现在分享给大家,希望可以做个参考。

什么是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
29
public 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
23
public 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
31
public 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
19
public 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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部