1. 程式人生 > >NIO複製檔案的三種方式對比

NIO複製檔案的三種方式對比

下面對NIO複製檔案的三種方式進行對比:

方式一:利用通道完成檔案的複製(非直接緩衝區)

@Test
public void copyFirst(){
		
		// 為了比較效率,記錄程式執行時間
		long startTime = System.currentTimeMillis();  // 開始時間
		
		// 1 宣告輸入輸出流
		FileInputStream fis = null;
		FileOutputStream fos = null;
		// 2 宣告通道
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		
		try {
			// 3 建立輸入輸出流
			fis = new FileInputStream("C:/Java/NIO.pdf");
			fos = new FileOutputStream("C:/Java/newNIO.pdf");
			
			// 4 獲取通道
			inChannel = fis.getChannel();
			outChannel = fos.getChannel();
			
			// 5 分配指定大小的緩衝區
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			
			// 6 將通道中的資料存入快取區中
			while(inChannel.read(buffer) != -1){
				buffer.flip();  // 切換到讀取資料的模式
				// 7 將快取區中的資料寫入通道中
				outChannel.write(buffer);
				buffer.clear();  // 清空快取區
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(outChannel != null){
				try{
					outChannel.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if(inChannel != null){
				try{
					inChannel.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if(fos != null){
				try{
					fos.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if(fis != null){
				try{
					fis.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
		}
		
		// 記錄結束時間
		long endTime = System.currentTimeMillis();
		System.out.println("用通道完成檔案的複製(非直接緩衝區)耗時為" + (endTime - startTime) + "秒");
	}
	

執行三次的時間分別為:

用通道完成檔案的複製(非直接緩衝區)耗時為1220秒

用通道完成檔案的複製(非直接緩衝區)耗時為1213秒

用通道完成檔案的複製(非直接緩衝區)耗時為1226秒

第二種方法:使用直接緩衝區完成檔案的複製(記憶體對映檔案)

@Test
public void copySecond(){
		
		long startTime = System.currentTimeMillis();
		
		FileChannel inChannel = null;
		FileChannel outChannel = null;		
		
		try {
			// 獲取通道
			inChannel = FileChannel.open(Paths.get("C:/Java/NIO.pdf"), StandardOpenOption.READ);
			outChannel = FileChannel.open(Paths.get("C:/Java/newNIO.pdf"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
			
			// 設定記憶體對映檔案
			MappedByteBuffer imb = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
			MappedByteBuffer omb = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
			
			// 直接對緩衝區進行資料的讀寫操作
			byte[] data = new byte[imb.limit()];
			imb.get(data);
			omb.put(data);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(inChannel != null){
				try {
					inChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outChannel != null){
				try {
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		// 記錄結束時間
		long endTime = System.currentTimeMillis();
		System.out.println("使用直接緩衝區完成檔案的複製(記憶體對映檔案)耗時為" + (endTime - startTime) + "秒");
	}

執行三次的時間分別為:

使用直接緩衝區完成檔案的複製(記憶體對映檔案)耗時為107秒

使用直接緩衝區完成檔案的複製(記憶體對映檔案)耗時為112秒

使用直接緩衝區完成檔案的複製(記憶體對映檔案)耗時為107秒

方式三:通道之間的資料傳輸(直接快取區) 

@Test
public void copyThird(){
		
		long startTime = System.currentTimeMillis();
		
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		
		try {
			inChannel = FileChannel.open(Paths.get("C:/Java/NIO.pdf"), StandardOpenOption.READ);
			outChannel = FileChannel.open(Paths.get("C:/Java/newNIO.pdf"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
			inChannel.transferTo(0, inChannel.size(), outChannel);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(inChannel != null){
				try {
					inChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outChannel != null){
				try {
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("通道之間的資料傳輸(直接快取區)耗時為" + (endTime - startTime) + "秒");
	}

執行三次的時間分別為:

通道之間的資料傳輸(直接快取區)耗時為73秒

通道之間的資料傳輸(直接快取區)耗時為64秒

通道之間的資料傳輸(直接快取區)耗時為68秒