NIO三大核心,Selector,channel,Buffer
NIO面向缓冲区编程,是非阻塞的
package com.zg.nio;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* @Auther: zhaoss
* @Date: 2022/8/6 - 08 - 06 - 15:12
* @Description: com.zg.nio
* @version: 1.0
*/
public class NioFileChannel01 {
public static void main(String[] args) throws IOException {
String str = "hello , zg";
FileOutputStream fileOutputStream = new FileOutputStream("D:\\file01.txt");
//通过fileOutputStream 获取对应的FileChannel
FileChannel fileChannel = fileOutputStream.getChannel();
//创建一个缓冲区
// Buffer也就是由装有特定基本类型数据的一块内存缓冲区和操作数据的4个指针变量
// (mark标记,position位置, limit界限,capacity容量)组成
//capacity容量,即可以容纳的最大数据量,在缓存区创建时被设定且不可改变
//Limit,表示缓冲区当前的终点,不能对缓冲区超过极限的位置进行读写操作,极限是可以修改的
//position 位置,下一个要被读或写的元素索引,每次读写缓冲区数据时 都会改变值,为下一次的读写做准备
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
byteBuffer.put(str.getBytes());
/*
flip():Buffer有两种模式,写模式和读模式。在写模式下调用flip()之后,Buffer从写模式变成读模式。
那么limit就设置成了position当前的值(即当前写了多少数据),postion会被置为0,以表示读操作从缓存的头开始读,mark置为-1。
也就是说调用flip()之后,读/写指针position指到缓冲区头部,并且设置了最多只能读出之前写入的数据长度(而不是整个缓存的容量大小)。
public final Buffer flip() {
limit = position; //读数据不能超过 position
position = 0; //position被初始化
mark = -1; //
return this;
}
*/
//读写切换
byteBuffer.flip();
//将byteBuffer写入fileChnnel
// public int read(ByteBuffer dst)从通道中读取数据存入缓冲区
// public int write(ByteBuffer src) 把缓冲区中数据写入通道
fileChannel.write(byteBuffer);
fileOutputStream.close();
}
}
package com.zg.nio;
import org.springframework.cglib.core.Converter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* @Auther: zhaoss
* @Date: 2022/8/6 - 08 - 06 - 16:31
* @Description: com.zg.nio
* @version: 1.0
*/
public class NioFileChannel02 {
public static void main(String[] args) throws IOException {
File file = new File("D:\\file01.txt");
FileInputStream inputStream = new FileInputStream(file);
//通过 inputStream 获取对应的FileChannel -> 实际类型 FileChannelImpl
FileChannel fileChannel = inputStream.getChannel();
//创建缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
//将通道数据读入到buffer中
fileChannel.read(byteBuffer);
//将buffer中的字节转为字符串
System.out.println(new String(byteBuffer.array())); //byteBuffer.array() 返回byteBuffer中的hb
inputStream.close();
}
}
package com.zg.nio;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* @Auther: zhaoss
* @Date: 2022/8/6 - 08 - 06 - 17:14
* @Description: com.zg.nio
* @version: 1.0
*/
public class NioFileChannel03 {
public static void main(String[] args) throws IOException {
String str1 = "D:\\file01.txt";
String str2 = "D:\\file02.txt";
FileInputStream fileInputStream = new FileInputStream(str1);
FileChannel channel01 = fileInputStream.getChannel();
FileOutputStream fileOutputStream = new FileOutputStream(str2);
FileChannel channel02 = fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
//不知道文件多大,所以用while读取
while (true){
/*
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
*/
//清除缓存,重要
//byteBuffer.clear(); //清空数据,标志位置为-1. 如果没有,则read循环读取为0,因为position和limit相等了
int read = channel01.read(byteBuffer);
System.out.println("read="+read);
if (read==-1){ //-1表示读完,
break;
}
//将buffer中的数据写入到channel02
byteBuffer.flip(); //此时position =0 ,limit=10
channel02.write(byteBuffer); //写,则position 会跑到写的最后一位,postion = 10.
//p16
}
//关闭流
fileInputStream.close();
fileOutputStream.close();
}
}