16、New IO

16、New IO

1、为什么要使用NIO
NIO是JDK1.4加入发新包,NIO的创建目的是为了让java程序员可以实现高速I/O而无需编写自定义的本机代码。NIO将最耗时的I/O操作(即填充和提取缓冲区)转移回操作系统,因而可以极大的提高速度
2、流与块的比较
原来的I/O库与NIO最重要的区别是数据打包和传输的方式,原来的I/O以流的方式处理数据。而NIO以块的方式来处理数据
面向流的I/O系统一次一个字节的处理数据,一个输入流产生一个字节的数据,一个输出流消耗一个字节的数据,不利的一面是,面向流的I/O通常很慢
一个面向块的I/O系统以块的形式处理数据,每一个操作都作在下一步产生或者消耗一个数据块,按块处理数据比按字节处理数据要快很多,但是面向块的I/O缺少一下面向流的I/O所具有的优雅和简单。
3、缓冲区
在NIO中,所有数据都是用缓冲区处理的,在读取数据时,它直接读到缓冲区中,在写入数据时,她是写入到缓冲区中的,任何时候访问NIO中的数据,都是将它放入缓冲区中
缓冲区实质是一个数组,通常它是一个字节数组,但是也可以使用其他种类的数组,但是缓冲区不仅仅是一个数组,缓冲区提供了对数据的结构化访问,而且可以跟踪系统的读写进程
4、缓冲区类型
最常用的缓冲区类型是ByteBuffer,一个ByteBuffer可以在其底层字节数组上进行get/set操作(即字节的读取和设置)。ByteBuffer不是NIO中唯一的缓冲区类型,事实上每一种基本类型都有一个缓冲区类型
ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer
在这里插入图片描述

import java.nio.ByteBuffer;

public class NIODemo {

	public static void main(String[] args) {

		//创建一个字节缓冲区,申请内存空间为8字节allocate(分配)
		ByteBuffer buf=ByteBuffer.allocate(8);
		
		System.out.println("position="+buf.position());
		System.out.println("limit="+buf.limit());
		System.out.println("capacity="+buf.capacity());
		
		System.out.println("~~~~~~~~~~~~~");
		
		//向缓冲区写入数据
		buf.put((byte)10);
		buf.put((byte)20);
		buf.put((byte)30);
		buf.put((byte)40);
		System.out.println("position="+buf.position());
		System.out.println("limit="+buf.limit());
		System.out.println("capacity="+buf.capacity());
		
		//缓冲区的反转
		buf.flip();
		System.out.println("~~~~~~~~~~~~~");
		System.out.println("position="+buf.position());
		System.out.println("limit="+buf.limit());
		System.out.println("capacity="+buf.capacity());
		
		//hasRemaining告知当前位置和限制之间是否有元素
		if(buf.hasRemaining()) {
			//remaining返回当前位置与限制之间的元素数
			for(int i=0;i<buf.remaining();i++) {
				byte b=buf.get(i);
				System.out.println(b);
			}
		}
		
		System.out.println("~~~~~~~~~~~~~");
		System.out.println("position="+buf.position());
		System.out.println("limit="+buf.limit());
		System.out.println("capacity="+buf.capacity());
	}

}

position=0
limit=8
capacity=8
·············
position=4
limit=8
capacity=8
··········
position=0
limit=4
capacity=8
10
20
30
40
···········
position=0
limit=4
capacity=8

Buffer源码
在这里插入图片描述
5、通道:Channel

Channel是一个对象,可以通过它读取和写入数据,拿NIO和原来的I/O做一个比较,通道就是一个流。
正如前面踢到的,所有数据都通过Buffer对象来处理,您永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区,同样,您不会 直接从通道中读取字节,而是将数据从通道读入缓冲区,再从很清楚获取这个字节
在这里插入图片描述

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

import javax.swing.Icon;

/*
 * 比较IO操作的性能比较
 * 1、内存映射最快
 * 2、NIO读写文件
 * 3、使用缓冲的IO流
 * 
 */

public class CopyFileDemo {
	
	
	private static void randomAccessFileCopy() throws Exception {
		RandomAccessFile in=new RandomAccessFile("d:\\液化.jpg","r");
		RandomAccessFile out=new RandomAccessFile("d:\\test\\液化.jpg","rw");
		
		FileChannel fcIn=in.getChannel();
		FileChannel fcOut=out.getChannel();
		
		long size=fcIn.size();//输入流的字节大小
		//输入流的缓冲区
		MappedByteBuffer inBuf=fcIn.map(MapMode.READ_ONLY,0, size);
		//输出流的缓冲区
		MappedByteBuffer outBuf=fcOut.map(MapMode.READ_WRITE,0, size);
		
		for(int i=0;i<size;i++) {
			outBuf.put(inBuf.get());
		}
		//关闭通道是会写入数据块
		fcIn.close();
		fcOut.close();
		in.close();
		out.close();
		System.out.println("copy success");
		
	}
	
	/*
	 * 通过文件通道实现文件的复制
	 */
	public static void copyFile() throws Exception {
		
			//创建一个输入文件的通道
			FileInputStream fis=new FileInputStream("d:\\液化.jpg");
			FileChannel fcIn=fis.getChannel();
			
			//创建一个输出文件的通道
			FileOutputStream fos=new FileOutputStream("d:\\test\\液化.jpg");
			FileChannel fcOut=fos.getChannel();
			
			ByteBuffer buf=ByteBuffer.allocate(1024);
			while(fcIn.read(buf)!=-1) {
				//反转
				buf.flip();
				fcOut.write(buf);
				buf.clear();
			}
			
			fcIn.close();
			fcOut.close();
			System.out.println("copy success");
		
	}

	public static void main(String[] args) {

		try {
			//copyFile();
			randomAccessFileCopy();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

6、path接口

在这里插入图片描述

import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathFileDome {

	public static void main(String[] args) {

		File file=new File("c:\\test\\液化.jpg");
		
		//Path
		Path p1=Paths.get("c:\\test\\液化.jpg");
		System.out.println(p1);
		
		Path p2=file.toPath();
		System.out.println(p2);
		
		FileSystems.getDefault().getPath("c:\\test\\液化.jpg");
		
	}

}

7、Files工具类
在这里插入图片描述

		//Files工具类
		Path p4=Paths.get("c:\\test\\vinec.txt");
		String info="村花到我家,小河流水哗啦啦";
//		//StandardOpenOption.APPEND追加字节
//		try {
//			Files.write(p4, info.getBytes("GBk"), StandardOpenOption.APPEND);
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		//读取文件
		byte[] bytes;
		try {
			bytes = Files.readAllBytes(p4);
			System.out.println(new String(bytes));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//复制文件,StandardCopyOption.REPLACE_EXISTING文件存在
//		try {
//			Files.copy(p3, Paths.get("d:\\液化.jpg"),StandardCopyOption.REPLACE_EXISTING);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		
		//移动文件
//		try {
//			Files.move(p3, Paths.get("d:\\液化.jpg"),StandardCopyOption.REPLACE_EXISTING);
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//		e.printStackTrace();
//		}
	
		
		
		//删除文件
//		try {
//			Files.delete(p3);
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//		e.printStackTrace();
//		}

在这里插入图片描述

		//创建新目录,除了最后一个部件,其他必须存在
//		try {
//			Files.createDirectories(Paths.get("d:\\\\BB"));
//			//创建多级不存在的目录
//			//Files.createDirectories(Path);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		
		
		//创建文件
//		try {
//			Files.createDirectories(Paths.get("d:\\BB.txt"));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值