Netty(三)- NIO三大组件之Channel
创始人
2024-03-19 16:29:51
0

文章目录

  • 一、Channel 基本介绍
  • 二、FileChannel 类
  • 三、Channel 应用案例
    • 1. 应用实例 1 - 本地文件写数据
    • 2. 应用实例 2 - 本地文件读数据
    • 3. 应用实例 3 - 使用一个Buffer 完成文件读取、写入
    • 4. 应用实例 4 - 拷贝文件transferFrom方法

一、Channel 基本介绍

  1. NIO的通道类似于流,但有些区别如下:
    通道可以同时进行读写,而流只能读或者只能写;
    通道可以实现异步读写数据;
    通道可以从缓冲区读数据,也可以写数据到缓冲区;
    在这里插入图片描述
  2. BIO 中的 stream 是单向的,例如 FileInputStream 对象只能进行读取数据的操作,而 NIO 中的Channel(通道)是双向的,可以读操作,也可以写操作 ;
  3. Channel在NIO中是一个接口
    public interface Channel extends Closeable{}
  4. 常用的 Channel 类有:FileChannel、DatagramChannel、ServerSocketChannel 和 SocketChannel;【ServerSocketChanne 类似 ServerSocket , SocketChannel 类似 Socket】
  5. FileChannel 用于文件的数据读写,DatagramChannel 用于 UDP 的数据读写,ServerSocketChannel 和 SocketChannel 用于 TCP 的数据读写;

二、FileChannel 类

FileChannel 主要用来对本地文件进行 IO 操作,常见的方法有:

// 站在Buffer角度看,read in 数据到Buffer,从Bufferwrite out Channel
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) //把数据从当前通道复制给目标通道

三、Channel 应用案例

1. 应用实例 1 - 本地文件写数据

实例要求:
(1)用 ByteBuffer(缓冲) 和 FileChannel(通道), 将 “hello,你好” 写入到 file01.txt 中;
(2)文件不存在就创建;

import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;public class NIOFileChannel01 {public static void main(String[] args) throws Exception{String str = "hello,你好";// 创建一个输出流FileOutputStream fileOutputStream = new FileOutputStream("D:\\GitHub\\NettyDemo\\file01.txt");// 通过 fileOutputStream 获取对应的 FileChannel// 这个 fileChannel 真实类型是 FileChannelImplFileChannel fileChannel = fileOutputStream.getChannel();// 创建一个缓冲区 ByteBufferByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 将 str 放入 byteBufferbyteBuffer.put(str.getBytes());// 对byteBuffer 进行flipbyteBuffer.flip();// 将byteBuffer 数据写到 fileChannelfileChannel.write(byteBuffer);fileOutputStream.close();}
}

2. 应用实例 2 - 本地文件读数据

(1)使用 ByteBuffer(缓冲) 和 FileChannel(通道), 将 file01.txt 中的数据读入到程序,并显示在控制台;
(2)假定文件已经存在;

public class NIOFileChannel02 {public static void main(String[] args) throws Exception {// 创建文件的输入流File file = new File("D:\\GitHub\\NettyDemo\\file01.txt");FileInputStream fileInputStream = new FileInputStream(file);// 通过fileInputStream 获取对应的FileChannel -> 实际类型  FileChannelImplFileChannel fileChannel = fileInputStream.getChannel();// 创建缓冲区ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());// 将通道的数据读入到BufferfileChannel.read(byteBuffer);// 将byteBuffer 的字节数据 转成StringSystem.out.println(new String(byteBuffer.array()));fileInputStream.close();}
}

输出:

hello,你好

3. 应用实例 3 - 使用一个Buffer 完成文件读取、写入

实例要求:
(1)使用 FileChannel(通道) 和 方法 read 、 write,完成文件的拷贝;
(2)拷贝一个文本文件 file01.txt , 放在项目下即可;

在这里插入图片描述

public class NIOFileChannel03 {public static void main(String[] args) throws Exception {FileInputStream fileInputStream = new FileInputStream("1.txt");FileChannel fileChannel01 = fileInputStream.getChannel();FileOutputStream fileOutputStream = new FileOutputStream("2.txt");FileChannel fileChannel02 = fileOutputStream.getChannel();ByteBuffer byteBuffer = ByteBuffer.allocate(512);// 循环读取while (true) {// 这里有一个重要的操作,一定不要忘了/*public Buffer clear() { // clear源码position = 0;limit = capacity;mark = -1;return this;}*/// 清空buffer// 如果不clear,此时position=limit,则read的返回值为0,退不出循环,还会一直重复写byteBuffer.clear();int read = fileChannel01.read(byteBuffer);System.out.println("read = " + read);// 表示读完if(read == -1) {break;}// 将buffer 中的数据写入到 fileChannel02 -- 2.txtbyteBuffer.flip();fileChannel02.write(byteBuffer);}// 关闭相关的流fileInputStream.close();fileOutputStream.close();}
}

4. 应用实例 4 - 拷贝文件transferFrom方法

实例要求:
(1)使用 FileChannel(通道) 和 transferFrom方法,完成文件的拷贝;
(2)拷贝一张图片;

public class NIOFileChannel04 {public static void main(String[] args)  throws Exception {// 创建相关流FileInputStream fileInputStream = new FileInputStream("D:\\GitHub\\NettyDemo\\a.png");FileOutputStream fileOutputStream = new FileOutputStream("D:\\GitHub\\NettyDemo\\a2.png");// 获取各个流对应的fileChannelFileChannel sourceChannel = fileInputStream.getChannel();FileChannel destChannel = fileOutputStream.getChannel();// 使用transferForm完成拷贝destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());// 关闭相关通道和流sourceChannel.close();destChannel.close();fileInputStream.close();fileOutputStream.close();}
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...