1. 程式人生 > >java中高效率本地整體檔案的複製遷移研究

java中高效率本地整體檔案的複製遷移研究

package io;

import java.io.*;

public class IoMove {
	public static void main(String[] args) {
		try {
			// 傳入兩個資料夾路徑,其中在Windows中使用的分隔符是"\\"
			long begintime = System.currentTimeMillis();
			System.out.println("開始時間:"+begintime);
			
			CopyFile("F:\\photo\\20160624院畢業典禮", "D:\\1234");
			
			long endtime = System.currentTimeMillis();
			System.out.println("結束時間:"+endtime);
			System.out.println("一共耗時:"+formatDuring(endtime-begintime));
		} catch (Exception ex) {
		}
		System.out.println("Copy File is over!");

	}

	// 複製資料夾的方法,開始的時候是兩個資料夾
	public static void CopyFile(String source, String destin) throws Exception {
		File path1 = new File(source);
		File path2 = new File(destin);

		// 如果源目錄不存在,那就不用複製了,
		if (path1.exists()) {
			// Create destination folder,如果目標目錄不存在,就建立目標目錄,因為沒有目錄檔案複製不過去的
			if (!path2.exists()) {
				path2.mkdirs();
			}

			// 取得源目錄下面的所有檔案和資料夾
			File[] items = path1.listFiles();
			FileInputStream fis = null;
			FileOutputStream fos = null;

			// 取得所有檔案和資料夾之後,遍歷處理,如果是檔案,就複製檔案,如果是資料夾,則遞迴資料夾下面的檔案和資料夾
			
			for (File item : items) {
				// 如果是檔案才進行復制
				if (item.isFile()) {
					// 輸入輸出流的兩個常用建構函式,其中在用來了一個欄位File.separator,先用輸入流讀取檔案,然後用輸出流寫檔案到目標位置,完成複製功能
					try {
						fis = new FileInputStream(item);
						fos = new FileOutputStream(path2 + File.separator + item.getName());
						byte[] b = new byte[1024];
						for (int i = 0; (i = fis.read(b)) != -1;) {
							fos.write(b, 0, i);
							fos.flush();
						}
					} catch (Exception e) {
					} finally {
						// close the Stream關閉資源啊,什麼異常處理的就不寫,自己補上吧
						fos.close();
						fis.close();
					}
				}
				// 如果是資料夾,遞迴資料夾
				else {
					CopyFile(item.getPath(), path2 + File.separator + item.getName());
				}
			}
		} else {
			System.out.println("source path:" + source + " is not exists!");
		}
	}
	

	/** 
	 *  
	 * @param 要轉換的毫秒數 
	 * @return 該毫秒數轉換為 * days * hours * minutes * seconds 後的格式 
	 * @author fy.zhang 
	 */  
	public static String formatDuring(long mss) {  
	    long days = mss / (1000 * 60 * 60 * 24);  
	    long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);  
	    long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);  
	    long seconds = (mss % (1000 * 60)) / 1000;  
	    return days + " days " + hours + " hours " + minutes + " minutes "  
	            + seconds + " seconds ";  
	}  

}

上邊這個是最基礎的檔案輸出輸入流,檔案大小是:1.64G   所用時間如圖:


接下來試下buffer

package io;

import java.io.*;

public class IoMove {
	public static void main(String[] args) {
		try {
			// 傳入兩個資料夾路徑,其中在Windows中使用的分隔符是"\\"
			long begintime = System.currentTimeMillis();
			System.out.println("開始時間:"+begintime);
			
			CopyFile("F:\\photo\\20160624院畢業典禮", "D:\\1234\\20160624院畢業典禮");
			
			long endtime = System.currentTimeMillis();
			System.out.println("結束時間:"+endtime);
			System.out.println("一共耗時:"+formatDuring(endtime-begintime));
		} catch (Exception ex) {
		}
		System.out.println("Copy File is over!");

	}

	// 複製資料夾的方法,開始的時候是兩個資料夾
	public static void CopyFile(String source, String destin) throws Exception {
		File path1 = new File(source);
		File path2 = new File(destin);

		// 如果源目錄不存在,那就不用複製了,
		if (path1.exists()) {
			// Create destination folder,如果目標目錄不存在,就建立目標目錄,因為沒有目錄檔案複製不過去的
			if (!path2.exists()) {
				path2.mkdirs();
			}

			// 取得源目錄下面的所有檔案和資料夾
			File[] items = path1.listFiles();
	        BufferedInputStream binput = null;
	        BufferedOutputStream boutput = null;
			FileInputStream fis = null;
			FileOutputStream fos = null;

			// 取得所有檔案和資料夾之後,遍歷處理,如果是檔案,就複製檔案,如果是資料夾,則遞迴資料夾下面的檔案和資料夾
			
			for (File item : items) {
				// 如果是檔案才進行復制
				if (item.isFile()) {
					// 輸入輸出流的兩個常用建構函式,其中在用來了一個欄位File.separator,先用輸入流讀取檔案,然後用輸出流寫檔案到目標位置,完成複製功能
					try {
						fis = new FileInputStream(item);
						fos = new FileOutputStream(path2 + File.separator + item.getName());
			            binput = new BufferedInputStream(fis);
			            boutput = new BufferedOutputStream(fos);
						byte[] b = new byte[1024];
						for (int i = 0; (i = binput.read(b)) != -1;) {
							boutput.write(b, 0, i);
							boutput.flush();
						}
					} catch (Exception e) {
					} finally {
						// close the Stream關閉資源啊,什麼異常處理的就不寫,自己補上吧
						boutput.close();
						binput.close();
						fos.close();
						fis.close();
					}
				}
				// 如果是資料夾,遞迴資料夾
				else {
					CopyFile(item.getPath(), path2 + File.separator + item.getName());
				}
			}
		} else {
			System.out.println("source path:" + source + " is not exists!");
		}
	}
	

	/** 
	 *  
	 * @param 要轉換的毫秒數 
	 * @return 該毫秒數轉換為 * days * hours * minutes * seconds 後的格式 
	 * @author fy.zhang 
	 */  
	public static String formatDuring(long mss) {  
	    long days = mss / (1000 * 60 * 60 * 24);  
	    long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);  
	    long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);  
	    long seconds = (mss % (1000 * 60)) / 1000;  
	    long milliseconds = mss % 1000;
	    return days + " days " + hours + " hours " + minutes + " minutes "  
	            + seconds + " seconds " + milliseconds + "毫秒";  
	}  

}


確實比單獨的FileInputStream流快

再試試FileChannel的用法

package io;

import java.io.*;
import java.nio.channels.FileChannel;

public class IoMove {
	public static void main(String[] args) {
		try {
			// 傳入兩個資料夾路徑,其中在Windows中使用的分隔符是"\\"
			long begintime = System.currentTimeMillis();
			System.out.println("開始時間:"+begintime);
			
			CopyFile("F:\\photo\\20160624院畢業典禮", "D:\\1234\\20160624院畢業典禮");
			
			long endtime = System.currentTimeMillis();
			System.out.println("結束時間:"+endtime);
			System.out.println("一共耗時:"+formatDuring(endtime-begintime));
		} catch (Exception ex) {
		}
		System.out.println("Copy File is over!");

	}

	// 複製資料夾的方法,開始的時候是兩個資料夾
	public static void CopyFile(String source, String destin) throws Exception {
		File path1 = new File(source);
		File path2 = new File(destin);

		// 如果源目錄不存在,那就不用複製了,
		if (path1.exists()) {
			// Create destination folder,如果目標目錄不存在,就建立目標目錄,因為沒有目錄檔案複製不過去的
			if (!path2.exists()) {
				path2.mkdirs();
			}

			// 取得源目錄下面的所有檔案和資料夾
			File[] items = path1.listFiles();
			FileChannel in = null;
	        FileChannel out = null;
			FileInputStream fis = null;
			FileOutputStream fos = null;

			// 取得所有檔案和資料夾之後,遍歷處理,如果是檔案,就複製檔案,如果是資料夾,則遞迴資料夾下面的檔案和資料夾
			
			for (File item : items) {
				// 如果是檔案才進行復制
				if (item.isFile()) {
					// 輸入輸出流的兩個常用建構函式,其中在用來了一個欄位File.separator,先用輸入流讀取檔案,然後用輸出流寫檔案到目標位置,完成複製功能
					try {
						fis = new FileInputStream(item);
						fos = new FileOutputStream(path2 + File.separator + item.getName());
						in = fis.getChannel();//得到對應的檔案通道
				        out = fos.getChannel();//得到對應的檔案通道
						in.transferTo(0, in.size(), out);//連線兩個通道,並且從in通道讀取,然後寫入out通道
					} catch (Exception e) {
					} finally {
						// close the Stream關閉資源啊,什麼異常處理的就不寫,自己補上吧
						in.close();
						out.close();
					}
				}
				// 如果是資料夾,遞迴資料夾
				else {
					CopyFile(item.getPath(), path2 + File.separator + item.getName());
				}
			}
		} else {
			System.out.println("source path:" + source + " is not exists!");
		}
	}
	

	/** 
	 *  
	 * @param 要轉換的毫秒數 
	 * @return 該毫秒數轉換為 * days * hours * minutes * seconds 後的格式 
	 * @author fy.zhang 
	 */  
	public static String formatDuring(long mss) {  
	    long days = mss / (1000 * 60 * 60 * 24);  
	    long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);  
	    long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);  
	    long seconds = (mss % (1000 * 60)) / 1000;  
	    long milliseconds = mss % 1000;
	    return days + " days " + hours + " hours " + minutes + " minutes "  
	            + seconds + " seconds " + milliseconds + "毫秒";  
	}  

}


速度又快了一些,當然跟直接用buffer也差不了太多,不過這個是屬於NIO的,保證了多執行緒情況下的安全,在併發的時候更有效率。我再試試直接用iava程式呼叫windows系統的cmd命令copy,據說這個效率更高

package io;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

public class IoMove {
	public static void main(String[] args) {
		try {
			// 傳入兩個資料夾路徑,其中在Windows中使用的分隔符是"\\"
			long begintime = System.currentTimeMillis();
			System.out.println("開始時間:" + begintime);

			copyFile("F:\\photo\\20160624院畢業典禮", "D:\\1234\\20160624院畢業典禮");

			long endtime = System.currentTimeMillis();
			System.out.println("結束時間:" + endtime);
			System.out.println("一共耗時:" + formatDuring(endtime - begintime));
		} catch (Exception ex) {
		}
		System.out.println("Copy File is over!");

	}

	// 複製資料夾的方法,開始的時候是兩個資料夾
	public static void copyFile(String source, String destin) throws Exception {
		File origin = new File(source);
		File target = new File(destin);
		// 如果源目錄不存在,那就不用複製了,
		if (origin.exists()) {
			if (!target.exists()) {
				target.mkdirs();
			}
			// 取得源目錄下面的所有檔案和資料夾
			File[] first = origin.listFiles();

			List<File> fileList = new LinkedList<>();
			for (File firstFile : first) {
				fileList.add(firstFile);
			}
			while (fileList.size() != 0) {
				// 移除第一個,判斷該檔案是資料夾還是檔案,做不同處理
				File tempFile = fileList.remove(0);
				if (tempFile.isDirectory()) {
					File[] second = tempFile.listFiles();
					for (File secondFile : second) {
						fileList.add(secondFile);
					}
					File path = new File(tempFile.getAbsolutePath().replace(source, destin));
					if (!path.exists()) {
						path.mkdirs();
					}
				} else {
					copyFileToTarget(tempFile, source, destin);
				}
			}
		} else {
			System.out.println("source path:" + source + " is not exists!");
		}
	}

	/**
	 * 複製到指定資料夾下的自定義目錄
	 * 
	 * @param fileName
	 *            原始檔名
	 * @param sourcePath
	 *            原始檔路徑
	 * @param destPath
	 *            目標檔案路徑
	 * @param customPath
	 *            自定義檔案目錄
	 */
	public static void copyFileToTarget(File file, String source, String destin) {
		String fileName = file.getName();
		StringBuilder cmd = new StringBuilder("cmd /c copy ");
		cmd.append(file.getAbsolutePath() + " ").append(file.getAbsolutePath().replace(source, destin) + " ");
		try {
			Runtime.getRuntime().exec(cmd.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @param 要轉換的毫秒數
	 * @return 該毫秒數轉換為 * days * hours * minutes * seconds 後的格式
	 * @author fy.zhang
	 */
	public static String formatDuring(long mss) {
		long days = mss / (1000 * 60 * 60 * 24);
		long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
		long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
		long seconds = (mss % (1000 * 60)) / 1000;
		long milliseconds = mss % 1000;
		return days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds " + milliseconds
				+ "毫秒";
	}

}

這個6了,看結果


但是我感覺有隱患,因為我用電腦做實驗,發現執行完之後真的是卡了一小會,是不是Process需要銷燬呢,可是我試了下waitfor再destroy結果非常慢,就沒有意義了,我還需要進一步確認下

經過我確認,Process這種是建立了一個隱藏的程序,並沒有隨著java程式的終止而停止的程序,真的很慢的說,網上這幫大騙子,我說怎麼跑完了java都終止了,電腦反倒是變卡了,在後臺跑程序,磁碟讀寫都他麼還滿著呢。所以用第三種方法應該是最靠譜的把。。。當然也可能是我才疏學淺,希望有懂得大佬教導一下。

ps--所謂的waitfor,destory方法什麼的我都試了,感覺就是讓java程式等後臺程序跑完了而已,並沒有什麼我想象中的呼叫了cmd什麼牛的方法,感覺還是io流讀寫把。。。。

相關推薦

java中高效率本地整體檔案複製遷移研究

package io; import java.io.*; public class IoMove { public static void main(String[] args) { try { // 傳入兩個資料夾路徑,其中在Windows中使用的分隔符是

Java筆記】IO流中四種檔案複製方式效率比較

位元組流檔案複製方式: (1)位元組流讀寫單個位元組 (2)位元組流讀寫位元組陣列 (3)位元組緩衝流讀寫單個位元組 (4)位元組緩衝流讀寫位元組陣列 import java.io.BufferedInputStream; import java.io.BufferedOutpu

JAVA NIO(三) 三種檔案複製方法與效率對比

檔案的複製最能體現io效率了.因為既需要讀取資料還需要寫出到硬碟中,下面提供了三種檔案複製的方法 可以對比一下 直接緩衝區與非直接緩衝區的效率對比.public class Nio { public static void main(String[] args) t

Java筆記】IO流中檔案複製及異常處理

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Main

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

傳統的I/O速度相對照較慢,它會成為系統性能的瓶頸。所以在java1.4之後提供了NIO,它是一種全新的流:它具有下面特性:        1.為全部的原是型別提供Buffer快取支援; 2.使用java.nio.charset.C

JAVA本地讀取檔案,解決中文亂碼問題

JAVA本地讀取檔案出現中文亂碼,查閱一個大神的部落格做一下記錄 import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.Buffered

JAVA高階基礎(30)---位元組輸入輸出流完成檔案複製

位元組輸入流 InputStream  注:更多方法請查詢API package org.lanqiao.inputstream.demo; import java.io.File; import java.io.FileInputStream; import ja

scp將本地檔案複製到遠端主機

scp可以將本地檔案複製到遠端主機,但是將該主機當跳板機複製到其他主機則沒法直接操作; host data     User data     ProxyCommand ssh [email protected] -p 2222 nc 192.1

Java -- 多執行緒檔案複製

題目描述: 實現檔案複製功能 多執行緒實現檔案從一個目錄複製到另一個目錄 @param sourceFile : 給定原始檔路徑名 @param desPath : 複製點檔案路徑 程式碼: package fileio20180924; import

java使用IO位元組流讀取複製檔案

具體程式碼如下: package com.copy; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.Fil

Lsyncd本地檔案複製到遠端機器

1. 設定ssh免密登入 主機A免密登入到主機B # 登入A主機,生成金鑰對 ssh-keygen -t rsa # 將公鑰複製到B主機 ssh-copy-id -i .ssh/id_rsa.pub [email protected] 2. 安

Java從web伺服器下載檔案本地

/*從伺服器中下載檔案到本地*/ /*url:檔案存放在伺服器的地址;target:要儲存的路徑*/ public String DownloadFile(String url,String target){ URLConnection con=null; URL theUrl=null; try { th

java 讀取本地excel 檔案,將excel內容轉換成java物件

操作工具 eclipse + maven 1. java操作excel所使用的jar包 poi-ooxml        <dependency>     <groupId>org.apache.poi</groupId>     <

Java實現檔案複製

程式碼實現複製檔案 /*  * 編寫一個程式,將d:\java目錄下的所有.java檔案複製到d:\jad目錄下,並將原來檔案的副檔名從.java改為.jad。 * <複製前改名> */public class CopyFolder {public stat

java IO流練習:檔案複製、遍歷子目錄、複製所有子目錄

import org.junit.Test; import java.awt.*; import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.t

java基礎-檔案複製,修改後綴名

package file; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStre

java實現檔案複製功能

簡單的檔案複製程式,當然只是複製過程中的一部分,仔細分析還有很多功能,比如判斷磁碟是否有足夠空間,效率等問題,這些問題後面會牽涉到 public void copyFolder(String oldPath,String newPath){ File nf = new F

Java API實現檔案複製

public class FileUtil { /** * 利用緩衝流複製檔案 * @param from原始檔 * @param to目標檔案 */ public static boolean bufCopy(String from,String t

java使用IO流完成檔案複製(文字、圖片、視訊)

一、使用位元組流實現 複製檔案中的地址可以是圖片或視訊。 1.基礎版: package com.uwo9.test01; import java.io.File; import java.io.FileInputStream; import java.io.Fi

31.Elasticsearch批量匯入本地Json檔案Java實現(ES檔案同步)

題記產品開發需要,我們需要將網際網路採集的資料儲存到ES中,以實現資料的全文檢索。網際網路採集的資料,往往格式雜亂,需要先進行資料清洗操作。而ES支援的入庫格式,json格式資料會相對方便些。本文主要介紹,如何將格式化的Json檔案批量插入到ES中。1、需提前做的工作1)設計