一、缓冲区
1.1 基本介绍
缓冲区(buffer):缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松的使用内存块,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况。Channel提供从文件、网络读取数据的渠道,但是读写或写入的数据都必须经过Buffer
1.2 Buffer类及其子类分析
Buffer类定义了所有的缓冲区都具有的四个属性来提供关于其包含的数据元素的信息:
对于java中的基本数据类型(Boolean除外),都有一个Buffer类型与之相对应,最常用的自然是ByteBuffer类(二进制数据),该类的主要方法如下:
代码演示
package com.bio;
import java.nio.IntBuffer;
public class BasicBuffer {
public static void main(String[] args) {
IntBuffer intBuffer = IntBuffer.allocate(10);
for (int i = 0; i < 10; i++) {
intBuffer.put(i);
}
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的数据读写。
2.2 FileChannel 类
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),把数据从当前通道复制给目标通道
2.3 实例操作
实例要求
- 使用前面学习后的ByteBuffer(缓冲)和FileChannel(通道)
- 将 ”小沙弥,真帅“写入到file01.txt中
- 从file01.txt 中读取数据显示到控制台
package com.nio;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NIOFileChannel01 {
static ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
public static void main(String[] args) throws FileNotFoundException {
readFile();
}
public static void writeFile() throws FileNotFoundException {
String str="小沙弥 真帅!";
FileOutputStream fileOutputStream = new FileOutputStream("d:\\file01.txt");
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 sourceChannel = fileInputStream.getChannel();
FileChannel targetChannel = fileOutputStream.getChannel();
targetChannel.transferFrom(sourceChannel,0,sourceChannel.size());
fileInputStream.close();
fileOutputStream.close();
}
}
推荐阅读上篇: 💥 一、Netty的特性介绍及解决的问题
|