【Java】第四十一节 NIO之Buffer和Channel

NIO(New IO)概念:

JDK1.4版本开始,JDK提供了新的IO操作API, NIO提供多路(non-blocking) 非阻塞式的高伸缩性网络I/O,从而提高了效率,NIO主要有三大核心组件:ChannelBufferSelector(此处仅介绍前两种)

一:Buffer之ByteBuffer

Buffer是一个抽象类,Buffer类型变量对应的对象代表一块缓冲区,ByteBufferCharBufferDoubleBufferFloatBufferIntBufferLongBufferShortBuffer类都是Buffer抽象类的子类,其中ByteBuffer最常用,下面就介绍一下ByteBuffer。

ByteBuffer常用方法:
  • static ByteBuffer allocate(int capacity):分配一个新的字节缓冲区
  • int capacity() :返回此缓冲区的容量,实际上直接将capacity成员属性值返回
  • ByteBuffer put(byte b):将字节类型数据写入当前位置的缓冲区,然后position+1,位置从0开始
  • byte[] array() :将ByteBuffer类型的数据转为byte数组
  • int position():返回缓冲区当前位置,实际上直接将position成员属性值返回
  • Buffer flip() :翻转缓冲区,将当前position值赋值给limit,并将position置零
  • byte get():读取缓冲区当前位置的字节,然后当前位置+1
  • Buffer clear():常用于要把缓存区清空的场景
  • boolean hasRemaining():开辟的缓存区是否还有空闲的空间
测试上面的方法:
package cn.jingpengchong.userinfo.test;

import java.nio.ByteBuffer;

public class Test02 {
	public static void main(String[] args) {
		//ByteBuffer.allocate:开辟空间缓存区
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		//capacity:获取缓存区空间大小
		int size = byteBuffer.capacity();
		System.out.println("capacity:\t" + size);
		byte a = 'c';
		//put:像缓存区存入数据,并将位置后移
		byteBuffer.put(a);
		byteBuffer.put(a);
		//array:将ByteBuffer类型的数据转为byte数组
		System.out.println("array:\t\t" + new String(byteBuffer.array()));
		//position:获取当前位置
		System.out.println("position:\t" + byteBuffer.position());
		//flip:将位置置零
		byteBuffer.flip();
		//get:获取一个数据,并将位置后移
		System.out.println("get:\t\t" + byteBuffer.get());
		//clear:将缓存区清空
		byteBuffer.clear();
		//hasRemaining:开辟的缓存区是否还有空闲的空间
		System.out.println("hasRemaining:\t" + byteBuffer.hasRemaining());
	}
}

运行结果如下:
在这里插入图片描述

二、Channel之FileChannel

Channel是一个接口,该接口类型变量指向的对象代表一个数据传输通道,Channel对象是面向缓冲区的:数据总是从通道读取到缓冲区(Buffer类型对象),或从缓冲区(Buffer类型对象)写入到通道中。Channel接口主要实现类如下,这里仅介绍FileChannel:

  • FileChannel:从文件中读写数据;
  • DatagramChannel:通过UDP读写网络中的数据;
  • SocketChannel:通过TCP读写网络中的数据;
  • ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样,对每一个新进来的连接都会创建一个SocketChannel。
FileChannel常用方法:

只能通过FileInputStream和FileOutputStream类中的getChannel()方法获取FileChannel对象,FileChannel类的常用方法如下:

  • int read(ByteBuffer dst):从通道的当前文件位置开始将数据读取到缓冲区,然后以实际读取的字节数更新文件位置;返回实际读取的字节数,如果已经到达通道的末尾,则返回-1
  • void close():关闭通道
  • int write(ByteBuffer src):从通道的当前文件位置开始将缓冲区中数据写入通道,然后文件位置用实际写入的字节数更新
测试上面的方法:复制文件
package cn.jingpengchong.userinfo.test;

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

public class Test02 {
	public static void main(String[] args) {
		//ByteBuffer.allocate:开辟空间缓存区
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

		FileInputStream fileInputStream = null;
		FileChannel inChannel = null;
		FileOutputStream fileOutputStream = null;
		FileChannel outChannel = null;
		try {
			fileInputStream = new FileInputStream("F:\\duia\\jdk api 1.8_google.CHM");
			inChannel = fileInputStream.getChannel();
			
			fileOutputStream = new FileOutputStream("F:\\duia\\abcd.CHM");
			outChannel = fileOutputStream.getChannel();
			
			while (inChannel.read(byteBuffer) != -1) {
				byteBuffer.flip();
				outChannel.write(byteBuffer);
				byteBuffer.clear();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(inChannel != null) {
				try {
					inChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outChannel != null) {
				try {
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

运行后,文件夹中的文件如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值