Java 详述NIO

1.NIO(即New IO)概念
JDK1.4版本开始,JDK提供了新的IO操作API, NIO提供多路(non-blocking) 非阻塞式的高伸缩性网络I/O,从而提高了效率,NIO主要有三大核心组件:Channel、Buffer和Selector。
2.Buffer类
Buffer是一个抽象类,Buffer类型变量对应的对象代表一块缓冲区,ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer类都是Buffer抽象类的子类,其中ByteBuffer最常用。
3.ByteBuffer常用方法:
① ByteBuffer allocate(int capacity【一个int类型的数据】):分配一个新的字节缓冲区。
静态方法,直接用类名调用,定义方法如下:

ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

此时 byteBuffer 表示一块缓冲区
②返回int类型
capacity() :返回此缓冲区的容量。
③byteBuffer. put(byte b):将字节类型数据写入当前位置的缓冲区,然后当前位置+1,位置从0开始。
④返回int类型
position():返回缓冲区当前位置,返回的int数据也是从0开始计算的

package sun;

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		byte a =1;
		byte b=2;
		byteBuffer.put(a);
		byteBuffer.put(b);
		int size = byteBuffer.capacity();
		System.out.println(size);
		System.out.println(byteBuffer.position());
	}
}

运行结果:
在这里插入图片描述
⑤Buffer flip() :翻转缓冲区,将position置零。调用方式:byteBuffer.flip();

package sun;

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		byte a = 1;
		byte b = 2;
		byteBuffer.put(a);
		byteBuffer.put(b);
		System.out.println(byteBuffer.position());
		byteBuffer.flip();
		System.out.println(byteBuffer.position());
	}
}

运行结果
在这里插入图片描述
⑥byte get()读取缓冲区当前位置的字节,然后当前位置+1,也是从0开始计算的。

package sun;

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		byte a = 1;
		byte b = 2;
		byteBuffer.put(a);
		byteBuffer.put(b);
		System.out.println(byteBuffer.get());  
		//如果没有参数值,就是返回当前位置的数值,因为put方法向后加一,所以还没有给第三个元素赋值,结果为0
		System.out.println(byteBuffer.get(0));
		System.out.println(byteBuffer.get(1));
	}
}

运行结果
在这里插入图片描述
⑦Buffer clear():清除缓冲区,位置归零。与byteBuffer.flip();用法相似,有覆盖的意思。
⑧byte[] array() :将ByteBuffer类型的数据转为byte数组。

package sun;

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(4);
		byte[] car =  byteBuffer.array();
		for (byte b : car) {
			System.out.println(b);
		}
	}
}

运行结果
在这里插入图片描述
⑨boolean hasRemaining():判断缓冲区“指针”指向的地方是否还有内存。

package sun;

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(3);
		System.out.println(byteBuffer.get());//position 0
		System.out.println(byteBuffer.hasRemaining());
		System.out.println(byteBuffer.get());//position 1
		System.out.println(byteBuffer.hasRemaining());
		System.out.println(byteBuffer.get());//position 2
		System.out.println(byteBuffer.hasRemaining());
	}
}

在这里插入图片描述

4.Channel是一个接口,该接口类型变量指向的对象代表一个数据传输通道,Channel对象是面向缓冲区的:文件中的数据总是从通道读取到缓冲区(Buffer类型对象),或从缓冲区(Buffer类型对象)写入到通道中再到新的文件中。

FileChannel:从文件中读写数据。
只能通过调用FileInputStream和FileOutputStream类中getChannel方法获取FileChannel对象,FileChannel类常用方法如下:
①返回int类型
read(ByteBuffer dst):从通道的当前文件位置开始将数据读取到缓冲区,然后以实际读取的字节数更新文件位置;返回实际读取的字节数,如果已达到通道末尾, 则返回-1
②返回void类型
close():关闭通道。
③返回int类型
write(ByteBuffer src):从通道的当前文件位置开始将缓冲区中数据写入通道,然后文件位置用实际写入的字节数更新。

package sun;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Test {

	public static void main(String[] args) {
			try {
			FileInputStream fileInputStream = new FileInputStream("D:\\1.txt");
			FileChannel fileChannel =fileInputStream.getChannel();
			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			try {
				while((fileChannel.read(byteBuffer))!=-1) {
					String result = new String(byteBuffer.array(),0,byteBuffer.position());  //String类的构造方法
					System.out.println(result);
					byteBuffer.clear();
					}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

在这里插入图片描述
但是这个文件的设置需要编码一样,eclipse的编码是UTF-8所以,要求这个文本文档的编码的也是UTF-8。
在这里插入图片描述
实现用管道和缓冲区复制文件。

package sun;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Test {

	public static void main(String[] args) {
			try {
			FileInputStream fileInputStream = new FileInputStream("D:\\1.txt");
			FileChannel inputfileChannel = fileInputStream.getChannel();
			
			FileOutputStream fileOutputStream = new FileOutputStream("D:\\6.txt");
			FileChannel outputfileChannel = fileOutputStream.getChannel();
			
			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			
			while((inputfileChannel.read(byteBuffer))!=-1) {  //从通道的当前文件位置开始将数据读取到缓冲区
				byteBuffer.flip();
				outputfileChannel.write(byteBuffer);   //开始将缓冲区中数据写入通道
				byteBuffer.clear();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值