NIO概述

2.2 NIO概述
NIO
	NIO ==> New IO(新IO), Non-Block IO(非阻塞IO)
	NIO非阻塞IO,运行当前程序在处理IO事务时,不会影响其他程序的运行,可以在不使用多线程的情况下,满足IO操作要求。
	三大核心部分:
		通道
			Channel
			文件操作,网络数据传递操作使用的通道
		缓冲
			Buffer
			缓冲使用可以提供操作效率,减少不必要的读写次数
		选择器
			Selector
			真·核心 老大 boss

在这里插入图片描述

2.3 Buffer Channel完成文件操作
2.3.1 常用API
java.nio.Buffer
Buffer缓冲区
	ByteBuffer 字节缓冲 常用
	ShortBuffer
	IntBuffer
	LongBuffer 
	CharBuffer 字节缓冲 常用
	FloatBuffer
	DoubleBuffer

常用方法:
	public static ByteBuffer allocate(int capacity);
		按照指定的字节数分配对应的缓冲区空间,保存字节数据
	public byte get(); 
		从字节缓冲区对象中读取一个byte类型数组
	public final Buffer flip();
		翻转缓冲区,回到缓冲区的开始位置。
	public static ByteBuffer wrap(byte[] arr);
		存入一个byte类型数组到缓冲区,会得到一个新的ByteBuffer
	public static ByteBuffer put(byte[] b);
		将字节数组存入缓冲去
		

Channel接口,通道接口
	FileChannel 文件操作通道
	DatagramChannel UDP协议数据包操作的Channel
	ServerSocketChannel TCP服务端ServerSocket对应Channel
	SocketChannel TCP客户端Socket对应Channel
首先操作文件,以FileChannel为例
	public long read(ByteBuffer buffer);
		从通道中读取数据到ByteBuffer中
	public long write(ByteBuffer buffer);
		从Buffer中写数据到通道中
	public long transferFrom(ReadableByteChannel src, long position, long count) 
	从指定srcChannel中,指定位置position开始,读取count个元素,到当前通道中
	文件复制操作。
	
	public long	transferTo(long position, long count, WritableByteChannel target) 
	将当前通道中的数据写入到target中,从当前通道的position位置开始,计数count
2.3.2 操作文件数据
package com.niofile;

import org.junit.Test;

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

/**
* @author Anonymous 2020/3/13 15:17
*/
public class FileNioTest {

   /*
   通过NIO写入数据到文件中的操作
    */
   @Test
   public void testNioFileWrite() throws IOException {
       // 1. 文件操作字节输出流
       FileOutputStream fos = new FileOutputStream("D:/aaa/1.txt");

       // 2. 利用文件操作输出字节流对象获取对应的Channel通道
       FileChannel foc = fos.getChannel();

       // 3. 准备一个缓冲区 4KB缓冲区
       ByteBuffer buffer = ByteBuffer.allocate(1024 * 4);

       // 4. 准备数据,放入缓冲区
       String str = "测试NIO";
       buffer.put(str.getBytes());

       // 5. 存在缓冲区数据放入之后,缓冲区指针发生改变,到达存入数据的末尾
       // 如果此时调用写入操作,会从存入缓冲区之后开始保存
       // 让缓冲区指针回到最初的起点,并且操作写入程序,只会保存缓冲区内的有效数据
       buffer.flip();

       // 6. 缓冲区数据写入到通道中
       foc.write(buffer);

       // 7. 关闭资源
       fos.close();
   }

   @Test
   public void testNioFileRead() throws IOException {
       // 1. 文件字节操作输入流
       FileInputStream fis = new FileInputStream("D:/aaa/1.txt");

       // 2. FileChannel
       FileChannel fic = fis.getChannel();

       // 3. 准备缓冲
       ByteBuffer buffer = ByteBuffer.allocate(1024);

       // 4. 从Channel读取数据保存到缓冲区中
       int read = fic.read(buffer);
       System.out.println(read);

       // 5. 展示数据
       // String(byte[] arr, int off, int count)
       System.out.println(new String(buffer.array(), 0, read));

       // 6. 关闭资源
       fis.close();
   }

   // 130
   @Test
   public void testCopyFile() throws IOException {
       long start = System.currentTimeMillis();
       // 1. 安排输出流和输入流
       FileInputStream fis = new FileInputStream("D:/aaa/1.mp4");
       FileOutputStream fos = new FileOutputStream("D:/aaa/2.mp4");

       // 2. 准备两个Channel
       FileChannel srcChannel = fis.getChannel();
       FileChannel dstChannel = fos.getChannel();

       // 3. 拷贝方法
       srcChannel.transferTo(0, srcChannel.size(), dstChannel);
       // dstChannel.transferFrom(srcChannel, 0, srcChannel.size());

       // 4. 关闭资源
       fos.close();
       fis.close();

       long end = System.currentTimeMillis();
       System.out.println("Time:" + (end - start));
   }

   // 300
   @Test
   public void testCopyUseBuffer() throws IOException {
       long start = System.currentTimeMillis();
       BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/aaa/1.mp4"));
       BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:/aaa/3.mp4"));

       int length = -1;
       byte[] buf = new byte[4 * 1024];

       while ((length = bis.read(buf)) != -1) {
           bos.write(buf, 0, length);
       }

       bos.close();
       bis.close();
       long end = System.currentTimeMillis();
       System.out.println("Time:" + (end - start));
   }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值