1. 程式人生 > >【Java】移動資料夾及其所有子檔案與子資料夾

【Java】移動資料夾及其所有子檔案與子資料夾

在Java移動資料夾及其所有子檔案與子資料夾可以有如下的一段簡單的方法來說明:

public static void moveFolder(String oldPath, String newPath) {
	//先複製檔案
	copyFolder(oldPath, newPath);
	//則刪除原始檔,以免複製的時候錯亂
	deleteDir(new File(oldPath));
}

不應該直接剪下檔案,防止在剪下的時候出錯,導致這樣那樣的問題。

在Java複製資料夾及其所有子檔案與子資料夾,在《【Java】利用檔案輸入輸出流完成把一個資料夾內的所有檔案拷貝的另一的資料夾的操作》(點選開啟連結)一文中已經詳細說過了。

關鍵是刪除資料夾及其子檔案與子資料夾。

在Java中,File類的delete()方法只能刪除為空的資料夾或者單個檔案,因此必須遍歷整個資料夾,先從最內層的資料夾中的檔案開始,進行遞迴刪除,具體方法如下:

// 刪除某個目錄及目錄下的所有子目錄和檔案
public static boolean deleteDir(File dir) {
	// 如果是資料夾
	if (dir.isDirectory()) {
		// 則讀出該資料夾下的的所有檔案
		String[] children = dir.list();
		// 遞迴刪除目錄中的子目錄下
		for (int i = 0; i < children.length; i++) {
			// File f=new File(String parent ,String child)
			// parent抽象路徑名用於表示目錄,child 路徑名字串用於表示目錄或檔案。
			// 連起來剛好是檔案路徑
			boolean isDelete = deleteDir(new File(dir, children[i]));
			// 如果刪完了,沒東西刪,isDelete==false的時候,則跳出此時遞迴
			if (!isDelete) {
				return false;
			}
		}
	}
	// 讀到的是一個檔案或者是一個空目錄,則可以直接刪除
	return dir.delete();
}
因此,整個方法連起來就是這個樣子,把C盤下的A資料夾及其所有子檔案與子資料夾,移動到F盤,並且重新命名:
import java.io.*;

public class CutTest {
	// 刪除某個目錄及目錄下的所有子目錄和檔案
	public static boolean deleteDir(File dir) {
		// 如果是資料夾
		if (dir.isDirectory()) {
			// 則讀出該資料夾下的的所有檔案
			String[] children = dir.list();
			// 遞迴刪除目錄中的子目錄下
			for (int i = 0; i < children.length; i++) {
				// File f=new File(String parent ,String child)
				// parent抽象路徑名用於表示目錄,child 路徑名字串用於表示目錄或檔案。
				// 連起來剛好是檔案路徑
				boolean isDelete = deleteDir(new File(dir, children[i]));
				// 如果刪完了,沒東西刪,isDelete==false的時候,則跳出此時遞迴
				if (!isDelete) {
					return false;
				}
			}
		}
		// 讀到的是一個檔案或者是一個空目錄,則可以直接刪除
		return dir.delete();
	}

	// 複製某個目錄及目錄下的所有子目錄和檔案到新資料夾
	public static void copyFolder(String oldPath, String newPath) {
		try {
			// 如果資料夾不存在,則建立新資料夾
			(new File(newPath)).mkdirs();
			// 讀取整個資料夾的內容到file字串陣列,下面設定一個遊標i,不停地向下移開始讀這個陣列
			File filelist = new File(oldPath);
			String[] file = filelist.list();
			// 要注意,這個temp僅僅是一個臨時檔案指標
			// 整個程式並沒有建立臨時檔案
			File temp = null;
			for (int i = 0; i < file.length; i++) {
				// 如果oldPath以路徑分隔符/或者\結尾,那麼則oldPath/檔名就可以了
				// 否則要自己oldPath後面補個路徑分隔符再加檔名
				// 誰知道你傳遞過來的引數是f:/a還是f:/a/啊?
				if (oldPath.endsWith(File.separator)) {
					temp = new File(oldPath + file[i]);
				} else {
					temp = new File(oldPath + File.separator + file[i]);
				}

				// 如果遊標遇到檔案
				if (temp.isFile()) {
					FileInputStream input = new FileInputStream(temp);
					// 複製並且改名
					FileOutputStream output = new FileOutputStream(newPath
							+ "/" + "rename_" + (temp.getName()).toString());
					byte[] bufferarray = new byte[1024 * 64];
					int prereadlength;
					while ((prereadlength = input.read(bufferarray)) != -1) {
						output.write(bufferarray, 0, prereadlength);
					}
					output.flush();
					output.close();
					input.close();
				}
				// 如果遊標遇到資料夾
				if (temp.isDirectory()) {
					copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
				}
			}
		} catch (Exception e) {
			System.out.println("複製整個資料夾內容操作出錯");
		}
	}

	public static void moveFolder(String oldPath, String newPath) {
		// 先複製檔案
		copyFolder(oldPath, newPath);
		// 則刪除原始檔,以免複製的時候錯亂
		deleteDir(new File(oldPath));
	}

	public static void main(String[] args) {
		moveFolder("c:/A", "f:/B");
	}

}