复制文件IO、NIO的写法比较

复制文件的比较

Io是web端不可不谈的一个重点,而复制则是一个典型的运用,从复制中可以了解各中io的运用及效率

原生IO
@Test
	public void executeInputStream() {
		String srcFile = "E:/电子书/白帽子讲Web安全.pdf";
		String tarFile = "E:/book.pdf";
		long start = System.currentTimeMillis();
		FileInputStream fis = null;
		FileOutputStream fos = null;
		File f = new File(srcFile);
		System.out.println("File  size="+f.length());
		try {
			fis = new FileInputStream(f);
			fos = new FileOutputStream(tarFile);
			int len = 0;
			byte[] b = new byte[1024];
			while ((len = fis.read(b)) != -1) {
				fos.write(b);
				fos.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		long end = System.currentTimeMillis();
		System.out.println("用时:" + (end - start) + "毫秒");

	}

console输出内容 这是运行过一次的第一次2600+ms 第二次的就变成了这个了,究其原因是是已有一份缓存内核缓存,导致第二次比第一次少很多,具体详见这篇文章
在这里插入图片描述
文本文档是这样的和NIO相差不太多,图像音频视频的话是比NIO慢许多的

BufferedInputStream Buff加成
	@Test
	public void runBufferedPutStream() {
		String srcFile = "E:/电子书/白帽子讲Web安全.pdf";
		String tarFile = "E:/book.pdf";
		long start = System.currentTimeMillis();
		int len = 0;
		byte[] b = new byte[1024];
		BufferedOutputStream fos = null;
		BufferedInputStream fis = null;
		try {
			fos = new BufferedOutputStream(new FileOutputStream(new File(tarFile)));
			fis = new BufferedInputStream(new FileInputStream(new File(srcFile)));
			while ((len = fis.read(b)) != -1) {
				fos.write(b);
				fos.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		long end = System.currentTimeMillis();
		System.out.println("用时:" + (end - start) + "毫秒");
	}

BufferedOutputStream与BufferedInputStream 我们都知道加了一层buff更吊了,加了一个缓存层效率确实高了一些
console打印
在这里插入图片描述
和原生IO相比可以看到确实提高一些,文件是相同的我这里没有打印,
这个多运行几次得到的时间是相同的,也佐证了这个已经加了buffer层,第一次第二次不会有区别了。

BufferedRead Writer
@Test
	public void runBufferedStreamReaderAndWriter() throws IOException {
		String srcFile = "E:/电子书/白帽子讲Web安全.pdf";
		String tarFile = "E:/book.pdf";
		long start = System.currentTimeMillis();
		BufferedReader br = new BufferedReader(new FileReader(new File(srcFile)));
		BufferedWriter fr = new BufferedWriter(new FileWriter(new File(tarFile)));
		int len = 0;
		char[] ch = new char[1024];
		while ((len = br.read(ch)) != -1) {
			fr.write(ch);
		}
		long end = System.currentTimeMillis();
		System.out.println("用时:" + (end - start) + "毫秒");
		br.close();
		fr.close();
	}

pdf类型的原因吧
在这里插入图片描述

FileChannel
@Test
	public void runChannelMapped() throws IOException {
		String srcFile = "E:/电子书/白帽子讲Web安全.pdf";
		String tarFile = "E:/book.pdf";
		long start = System.currentTimeMillis();
		// 获取通道
		// 读模式
		FileChannel inChannel = FileChannel.open(Paths.get(srcFile), StandardOpenOption.READ);
		// 读写模式
		FileChannel outChannel = FileChannel.open(Paths.get(tarFile), StandardOpenOption.WRITE, StandardOpenOption.READ,
				StandardOpenOption.CREATE);

		// 内存映射文件
		MappedByteBuffer inBuf = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
		MappedByteBuffer outBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());

		// 对缓冲区的数据进行读写操作
		byte[] by = new byte[inBuf.limit()];
		inBuf.get(by);
		outBuf.put(by);
		inChannel.close();
		outChannel.close();
		long end = System.currentTimeMillis();
		System.out.println("耗费时间:" + (end - start));
	}

channel 加mappedBytebuffer 内存映射得到的效果
在这里插入图片描述

这之后还有一个直接转换channel直接对接的方法,transferForm 效率最高

// 通道之间的数据传输,直接缓冲区
	@Test
	public void runTransFerChannel() throws IOException {
		String srcFile = "E:/电子书/白帽子讲Web安全.pdf";
		String tarFile = "E:/book.pdf";
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		long start = System.currentTimeMillis();
		try {
			// 读模式
			inChannel = FileChannel.open(Paths.get(srcFile), StandardOpenOption.READ);
			// 读写模式
			outChannel = FileChannel.open(Paths.get(tarFile), StandardOpenOption.WRITE, StandardOpenOption.READ,
					StandardOpenOption.CREATE);
			// inChannel.transferTo(0, inChannel.size(), outChannel);
			outChannel.transferFrom(inChannel, 0, inChannel.size());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			inChannel.close();
			outChannel.close();
		}

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

效率达到了最高
在这里插入图片描述

有一部分参考
https://www.cnblogs.com/-ROCKS/p/5770393.html

Guess you like

Origin blog.csdn.net/weixin_41086086/article/details/95476627