缓冲区(buffer):缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松的使用内存块,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况。Channel提供从文件、网络读取数据的渠道,但是读写或写入的数据都必须经过Buffer
Buffer类定义了所有的缓冲区都具有的四个属性来提供关于其包含的数据元素的信息:
对于java中的基本数据类型(Boolean除外),都有一个Buffer类型与之相对应,最常用的自然是ByteBuffer类(二进制数据),该类的主要方法如下:
代码演示
package com.bio;
import java.nio.IntBuffer;
public class BasicBuffer {
public static void main(String[] args) {
//创建一个buffer对象,设置容量为10,默认为16
IntBuffer intBuffer = IntBuffer.allocate(10);
//循环往buffer中放入数据
for (int i = 0; i < 10; i++) {
intBuffer.put(i);
}
//反转buffer 当需要切换 读/写操作时 必须要调用 filp()
intBuffer.flip();
//设置开始读取的索引位置
intBuffer.position(5);
//设置读取的最大索引位置
intBuffer.limit(8);
while(intBuffer.hasRemaining()){
System.out.println(intBuffer.get());
}
}
}
1.3
二、 Channel(通道)
2.1 基本介绍
NIO的通道类似于流,但是有些区别如下:
- 通道可以同时进行读写,而流只能读或者只能写
- 通道可以实现异步读写数据
- 通道可以从缓冲读取数据,也可以写数据到缓冲区中
- Channel在NIO中是一个接口public interface Channel extends Closeable{}
- 常用的Channel 类有:FileChannel、DatagramChannel、ServerSocketChannel和SocketChannel.
- FileChannel 用于文件的数据读写,DatagrapChannel 用于UDP的数据读写,ServerSocketChannel 和SocketChannel用于TCP的数据读写。
FileChannel主要用来对本地文件进行IO操作,常见的方法有
- 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),把数据从当前通道复制给目标通道
实例要求
- 使用前面学习后的ByteBuffer(缓冲)和FileChannel(通道)
- 将 ”小沙弥,真帅“写入到file01.txt中
- 从file01.txt 中读取数据显示到控制台
package com.nio;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NIOFileChannel01 {
//创建ByteBuffer对象
static ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
public static void main(String[] args) throws FileNotFoundException {
// writeFile();
readFile();
}
//将字符串写入到文件中
public static void writeFile() throws FileNotFoundException {
String str="小沙弥 真帅!";
//创建一个文件输入流
FileOutputStream fileOutputStream = new FileOutputStream("d:\file01.txt");
//通过文件输入流得到一个channel对象
FileChannel channel = fileOutputStream.getChannel();
//将数据写入到缓冲区中,并反转缓冲区
byteBuffer.put(str.getBytes());
byteBuffer.flip();
try {
channel.write(byteBuffer);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//关闭文件输入流
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//从文件中读取字符串显示到控制台
public static void readFile() throws FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream("d:\file01.txt");
FileChannel channel = fileInputStream.getChannel();
try {
channel.read(byteBuffer);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
byteBuffer.flip();
byte bytes[]=new byte[1024];
bytes = byteBuffer.array();
System.out.println(new String(bytes));
}
}
流程图:
实例 2
实验目的:巩固NIO中channel的使用
实验步骤:将图片使用 channel的transferFrom() 进行拷贝
package com.nio;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
public class NIOFileChannel02 {
public static void main(String[] args) throws Exception{
FileInputStream fileInputStream = new FileInputStream("d:\a1.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("d:\a2.jpg");
//获取各个流相对应的filechannel
FileChannel sourceChannel = fileInputStream.getChannel();
FileChannel targetChannel = fileOutputStream.getChannel();
//将数据从目标通道复制到当前通道
targetChannel.transferFrom(sourceChannel,0,sourceChannel.size());
//关闭各个流
fileInputStream.close();
fileOutputStream.close();
}
}



