1. 程式人生 > >java流的效能優化1-檔案複製

java流的效能優化1-檔案複製

傳統的I/O速度相對照較慢,它會成為系統性能的瓶頸。所以在java1.4之後提供了NIO,它是一種全新的流:它具有下面特性:

       1.為全部的原是型別提供Buffer快取支援;

2.使用java.nio.charset.Charset作為字元編碼解碼解決方式;

3.新增通道(Channel)物件,作為新的原始I/O抽象。

4.支援鎖和記憶體對映檔案的檔案訪問介面;

5.提供基於Selector的非同步網路I/O;

NIO是一種全新的流,跟流式的I/O不同,NIO是基於塊的,它以塊為基本單位處理資料。

在NIO中,最為重要的兩個元件是緩衝Buffer和通道Channel。

如圖這是他們指甲的關係

從上圖的關係看來。Channel是一個雙向的通道。就可以讀又能夠寫。

如今,從效能上來比較一下io和Nio的效能差異吧。這是一個檔案複製的樣例,檔案大小均為152m,快取設定成1m:

public class CopyFile {

	public static void main(String args[]) {
		String path = "E:\\temp_nio.tmp";

		String new_path = "E:\\demo\\nio.tmp";
		long start = System.currentTimeMillis();

		NioCopy(path, new_path);
		long end = System.currentTimeMillis();
		System.out.println("Nio拷貝檔案執行時間:"+(end-start));

		path="E:\\temp_cache_tmp";
		new_path="E:\\demo\\temp_cache_tmp";
		 start = System.currentTimeMillis();
		 IoCopy(path, new_path);
		 end = System.currentTimeMillis();
		System.out.println("Io拷貝檔案執行時間:"+(end-start));
	}

	/*
	 * Nio拷貝檔案
	 */
	public static void NioCopy(String path, String new_path) {
		try (FileInputStream fis = new FileInputStream(new File(path));
				FileOutputStream fos = new FileOutputStream(new File(new_path));
				FileChannel fisChannel = fis.getChannel();
				FileChannel fosChannel = fos.getChannel();) {
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			while (true) {
				buffer.clear();
				int len = fisChannel.read(buffer);
				if (len == -1) {
					break;
				}
				buffer.flip();
				fosChannel.write(buffer);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

	/*
	 * io拷貝檔案
	 */
	public static void IoCopy(String path, String new_path) {
		try (FileInputStream fis = new FileInputStream(new File(path));
				FileOutputStream fos = new FileOutputStream(new File(new_path));) {
			byte buffer[] = new byte[1024];
			while ((fis.read(buffer)) != -1) {
				fos.write(buffer);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}
}

執行時間的效率上還是會有差距的,事實上我們能夠依據設定快取的大小來加快兩者執行的效率。當然從理論上來說快取設定得越大越好。這樣讀取速度會非常的快。可是從實際的角度來說。這個是有非常大的問題,他會讓你server的記憶體耗光。讓你的gc收集次數加多。所以不同的環境下能夠依據自己的情況設定快取,我設定的是10m,例如以下圖所看到的,效率提高非常多。可是捨去的是大量的記憶體,事實上也能夠通過優化jvm的方式來提高一些系統的效率,這個我就不多說了。