0
点赞
收藏
分享

微信扫一扫

Channel基本介绍


基本介绍

1.NIO的通道类(Channel)似于流,或者理解为一个连接,但有些区别如下

  • ​通道可以同时进行读写,而流只能读或者只能写​
  • ​通道可以实现异步读写数据​
  • ​通道可以从缓冲读数据,也可以写数据到缓冲:​
  • Channel基本介绍_写数据


2.BIO 中的 stream 是单向的,例如 FileInputStream 对象只能进行读取数据的操作,而 NIO 中的通道(Channel)是双向的,可以读操作,也可以写操作。效率也就提高了

3.Channel在NIO中是一个接口public interface Channel extends Closeable{}

Channel基本介绍_写数据_02

4.常用的 Channel 类有:FileChannel、DatagramChannel、ServerSocketChannel 和 SocketChannel。【ServerSocketChanne 类似 ServerSocket , SocketChannel 类似 Socket】

Channel基本介绍_数据_03

5.FileChannel 用于文件的数据读写,DatagramChannel 用于 UDP 的数据读写,ServerSocketChannel 和 SocketChannel 用于 TCP 的数据读写。

FileChannel 类

FileChannel主要用来对本地文件进行 IO 操作,真正的实现类是FileChannelImpl,常见的方法有

  1. public int read(ByteBuffer dst) ,从通道读取数据并放到缓冲区中
  2. public int write(ByteBuffer src) ,把缓冲区的数据写到通道中
  3. public long transferFrom(ReadableByteChannel src, long position, long count),从目标通道中复制数据到当前通道
  4. public long transferTo(long position, long count, WritableByteChannel target),把数据从当前通道复制给目标通道

FileChannel 案例

本地文件写数据

/**
* @author TAO
* @description: 本地文件写数据
* @date 2021/6/8 0:02
*/
public class NIOFileChannel01 {

public static void main(String[] args) throws IOException {
String str = "hello Netty";
//创建一个输出流 -> channel
FileOutputStream fileOutputStream = new FileOutputStream("./file01.txt");

//通过fileOutputStream 获取 对应的FileChannel
//这个fileChannel 真实类型是 FileChannelImpl
FileChannel fileChannel = fileOutputStream.getChannel();

//创建一个缓冲区ByteBuffer
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

//将 str 放入 byteBuffer
byteBuffer.put(str.getBytes());

//对buffer 进行反转
byteBuffer.flip();

//将byteBuffer 数据写入到fileChannel
fileChannel.write(byteBuffer);
fileChannel.close();

}

}

Channel基本介绍_本地文件_04


Channel基本介绍_写数据_05


​在fileOutputStream中就包括了Channel,我们可以理解为在我们Java原生输出对象中就包含了Channel​

本地文件读数据

/**
* @author TAO
* @description: 本地文件读数据
* @date 2021/6/8 0:02
*/
public class NIOFileChannel02 {

public static void main(String[] args) throws Exception {
//创建文件输入流
File file = new File("./file01.txt");
FileInputStream fileInputStream = new FileInputStream(file);

//通过fileOutputStream 获取 对应的FileChannel
//这个fileChannel 真实类型是 FileChannelImpl
FileChannel fileChannel = fileInputStream.getChannel();

//创建一个缓冲区ByteBuffer
ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());

//将通道的数据读取到Buffer
fileChannel.read(byteBuffer);

//将 byteBuffer 的字节数据转换为String
System.out.println(new String(byteBuffer.array()));

fileInputStream.close();

}

}

使用一个Buffer完成文件读取

/**
* @author TAO
* @description: 使用一个Buffer完成文件读取
* @date 2021/6/21 1:10
*/
public class NIOFileChannel03 {

public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("./file01.txt");
FileChannel fileChannel1 = fileInputStream.getChannel();

FileOutputStream fileOutputStream = new FileOutputStream("./file02.txt");
FileChannel fileChannel2 = fileOutputStream.getChannel();

ByteBuffer byteBuffer = ByteBuffer.allocate(512);
while (true) {

byteBuffer.clear();//TODO 必须清空buffer 否则red是0 导致死循环
int red = fileChannel1.read(byteBuffer);
System.out.println("red===>"+red);
if (red == -1) {//表示读完
break;
}
//将buffer 中的数据写入到fileChannel2 --2.txt
byteBuffer.flip();
fileChannel2.write(byteBuffer);

}
//关闭相关流
fileInputStream.close();
fileOutputStream.close();
}
}

拷贝文件transferFrom 方法

/**
* @description: 拷贝文件transferFrom 方法
* @author TAO
* @date 2021/6/21 1:25
*/
public class NIOFileChannel04 {
public static void main(String[] args) throws IOException {

//创建相关流
FileInputStream fileInputStream = new FileInputStream("./test1.png");
FileOutputStream fileOutputStream = new FileOutputStream("./test2.png");

//获取各个流对应的FileChannel
FileChannel sourceCh = fileInputStream.getChannel();
FileChannel destCh = fileOutputStream.getChannel();

//使用transferFrom完成拷贝
destCh.transferFrom(sourceCh, 0, sourceCh.size());

//关闭相关通道和流
sourceCh.close();
destCh.close();
fileInputStream.close();
fileOutputStream.close();
}
}


举报

相关推荐

NIO基本组件Channel与Buffer

Java NIO基本组件Channel详解

线程基本介绍

React 基本介绍

rabbitMQ基本介绍

mongoDB基本介绍

VUE基本介绍

0 条评论