複製文件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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章