文件操作大全

/**
 * 文件操作大全(文件接口均是使用文件路徑名)
 * 1)創建文件
 * 2)刪除文件
 * 3)移動文件
 * 4)合併文件
 * 5)分割文件
 * 6)讀取文件
 * 7)列舉文件
 * @author Sking
 */
package file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.util.Random;

public class FileUtil {
	/***-----------1.創建文件---------***/
	
	/**
	 * 創建指定文件或目錄,成功創建則返回true,否則false, 
	 *       如果指定文件或目錄的父目錄不存在,則遞歸創建父目錄。
	 * @param destFile 待創建的指定文件或目錄
	 * @return 成功創建指定文件或目錄則返回true,
	 *                 如果目標文件或目錄已存在或創建失敗,返回false。
	 */
	public static boolean createFile(String destFile) {
		File file = new File(destFile); 
		if (file.exists()) { //判斷該文件是否存在
			System.out.println("目標文件已存在!");
			return false;//目標文件存在,返回false
		}
		//目標文件名是以文件分隔符結尾的,則爲目錄
		if (destFile.endsWith(File.separator)) {
			if(file.mkdirs()){
				System.out.println("目錄創建成功!");
				return true;
			}	
		}
		//判斷目標文件所在的目錄是否存在
		if (!file.getParentFile().exists()) {
			//如果目標文件父目錄不存在,則創建父目錄
			System.out.println("父目錄不存在,正在創建!");
			//遞歸創建父目錄,如果創建失敗則返回false
			if (!file.getParentFile().mkdirs()) {
				System.out.println("父目錄創建失敗!");
				return false;
			}
		}
		//創建目標文件
		try {
			if (file.createNewFile()) {
				System.out.println("創建文件成功!");
				return true;
			} else {
				System.out.println("創建文件失敗!");
				return false;
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("創建文件失敗!" + e.getMessage());
			return false;
		}
	}
	
	
	/***-----------2.刪除文件---------***/
	
	/**
	 * 刪除指定的目錄或文件,如果目錄不爲空則遞歸刪除,
	 *       成功刪除返回true,否則返回false。
	 * @param fileName 待刪除的文件或目錄
	 * @return 成功刪除指定的文件或目錄返回true,否則返回false
	 */
	public static boolean deleteFileOrDir(String fileName) {
		File file = new File(fileName);
		if (!file.exists()) {
			System.out.println("待刪除的目標文件不存在!");
			return false;
		} else {
			if (file.isFile()) {//刪除文件
				return deleteFile(fileName);
			} else {//刪除目錄
				return deleteDir(fileName);
			}
		}
	}

	/**
	 * 刪除指定文件,成功則返回true,否則返回false
	 * @param fileName 待刪除文件
	 * @return 成功刪除指定文件返回true,否則返回false
	 */
	public static boolean deleteFile(String fileName) {
		File file = new File(fileName);
		if (file.exists() && file.isFile()) {//文件存在
			if (file.delete()) {
				System.out.println("文件:" + fileName + "刪除成功!");
				return true;
			} else {
				System.out.println("文件" + fileName + "刪除失敗!");
				return false;
			}
		} else {
			System.out.println("待刪除文件不存在!");
			return false;
		}
	}

	/**
	 * 遞歸刪除指定目錄,成功則返回true,否則返回false
	 * @param dir 待刪除目錄
	 * @return 成功刪除指定目錄返回true,否則返回false
	 */
	public static boolean deleteDir(String dir) {
		//如果dir不以文件名稱分隔符結尾,自動添加文件分隔符。
		if (!dir.endsWith(File.separator)) {
			dir = dir + File.separator;
		}
		File dirFile = new File(dir);
		//文件不存在,或者不是一個目錄,返回false
		if (!dirFile.exists() || (!dirFile.isDirectory())) {
			System.out.println("待刪除目錄不存在!");
			return false;
		}
		boolean flag = true;
		//遞歸刪除子目錄或文件
		File[] files = dirFile.listFiles();//目錄下抽象路徑名數組
		for (int i = 0; i < files.length; i++) {
			if (files[i].isFile()) {//文件
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag) {
					break;//遇到一次不成功操作則直接退出,返回false
				}
			}
			else if (files[i].isDirectory()) {//子目錄
				flag = deleteDir(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}
			}
		}
		if (!flag) {
			System.out.println("刪除目錄失敗!");
			return false;
		}
		//刪除當前目錄
		if (dirFile.delete()) {
			System.out.println("目錄:" + dir + "刪除成功!");
			return true;
		} else {
			return false;
		}
	}
	
	
	/***-----------3.分割文件---------***/
	
	/**
	 * 分割文件操作
	 * @param name 待分割的文件名
	 * @param size 分割後的小文件大小,字節爲單位,
	 *                          如果爲負數,則默認大小爲源文件的一半。
	 * @return 分割後的文件路徑名數組
	 * @throws Exception 指定文件不存在,拋出異常
	 */
	public static String[] divide(String name, long size) throws Exception {
		File file = new File(name);
		if (!file.exists() || (!file.isFile())) {
			throw new Exception("指定文件不存在!");
		}
		File parentFile = file.getParentFile();// 父目錄抽象路徑
		long fileLength = file.length();
		if (size <= 0) {
			size = fileLength / 2;
		}
		int num=(int)(fileLength/size);
		if(fileLength % size != 0) 
			num++;//分割後的小文件個數
		String[] fileNames = new String[num];
		FileInputStream in = new FileInputStream(file);
		long end = 0;
		int begin = 0;
		// 根據要分割的數目輸出文件
		int index=file.getName().lastIndexOf('.');
		String suffix=file.getName().substring(index);//文件後綴
		for (int i = 0; i < num; i++) {
			String fileName=file.getName().substring(0,index)+i+suffix;
			File outFile = new File(parentFile, fileName);
			FileOutputStream out = new FileOutputStream(outFile);
			end += size;//將結束下標後移size
			end = (end > fileLength) ? fileLength : end;
			for (; begin < end; begin++) {
				out.write(in.read());
			}
			out.close();
			fileNames[i] = outFile.getAbsolutePath();
		}
		in.close();
		return fileNames;
	}
	
	
	/***-----------4.合併文件---------***/
	
	/**
	 * 合併文件操作
	 * @param fileNames 待合併的文件路徑名列表
	 * @param TargetFileName 合併後文件的路徑名
	 * @throws Exception IO異常
	 */
	public static void merge(String[] fileNames, String TargetFileName)
			throws Exception{
		File fin = null;
		File fout = new File(TargetFileName);
		FileOutputStream out = new FileOutputStream(fout);
		for (int i = 0; i < fileNames.length; i++) {
			fin = new File(fileNames[i]);
			FileInputStream in = new FileInputStream(fin);
			int c;
			while ((c = in.read()) != -1) {
				out.write(c);
			}
			in.close();
		}
		out.close();
	}
	
	/***-----------5.移動文件---------***/
	
	/**
	 * 移動指定的文件,已存在目標文件則不覆蓋
	 * @param sourceFileName 源文件
	 * @param targetFileName 目標文件
	 * @return 移動成功則返回true,否則false
	 */
	public static boolean moveFile(String sourceFileName, String targetFileName) {
		return moveFile(sourceFileName, targetFileName, false);
	}

	/**
	 * 移動源文件sourceFile到目標文件targetFile, 
	 *       根據isOverlay選擇在目標文件已存在情況下是否進行覆蓋
	 * @param sourceFile 源文件
	 * @param targetFile 目標文件
	 * @param isOverlay 是否進行覆蓋的標誌
	 * @return 如果成功移動文件返回true,否則返回false
	 */
	public static boolean moveFile(String sourceFile, String targetFile,
			boolean isOverlay) {
		// 判斷原文件是否存在
		File source = new File(sourceFile);
		if (!source.exists()) {
			System.out.println("源文件不存在!");
			return false;
		} else if (!source.isFile()) {
			System.out.println("源文件不是文件!");
			return false;
		}
		File target = new File(targetFile);
		if (target.exists()) {//目標文件是否存在
			if (isOverlay) {//目標文件存在,允許覆蓋目標文件
				// 刪除已存在的目標文件,無論目標文件是目錄還是文件
				System.out.println("目標文件已存在,準備刪除它!");
				if (!deleteFileOrDir(targetFile)) {
					System.out.println("目標文件刪除失敗");
					return false;
				}
			} else {//目標文件已存在,且不進行覆蓋,則返回false
				System.out.println("文件移動失敗,目標文件已存在!");
				return false;
			}
		} else {
			if (!target.getParentFile().exists()) {
				// 如果目標文件父目錄不存在,則創建目錄
				System.out.println("目標文件父目錄不存在,正在創建!");
				if (!target.getParentFile().mkdirs()) {
					System.out.println("創建目標文件父目錄失敗!");
					return false;
				}
			}
		}
		// 調用函數renameTo()移動原文件至目標文件
		if (source.renameTo(target)) {
			System.out.println("移動文件成功!");
			return true;
		} else {
			System.out.println("移動文件失敗!");
			return false;
		}
	}
	
	/**
	 *移動源目錄到目標目錄,不覆蓋已存在目錄
	 * @param sourceDirName 源目錄
	 * @param targetDirName 目標目錄
	 * @return 成功移動目錄則返回true,否則返回false
	 */
	public static boolean moveDir(String sourceDirName, String targetDirName) {
		return moveDir(sourceDirName, targetDirName, false);
	}

	/**
	 * 移動源目錄到目標目錄,根據標誌 isOverlay確定是否覆蓋已存在目錄
	 * @param sourceDirName 源目錄
	 * @param targetDirName 目標目錄
	 * @param isOverlay 是否覆蓋已存在目錄的標誌
	 * @return 成功移動則返回true,否則返回false
	 */
	public static boolean moveDir(String sourceDirName, String targetDirName,
			boolean isOverlay) {
		// 判斷原目錄是否存在
		File sourceDir = new File(sourceDirName);
		if (!sourceDir.exists()) {
			System.out.println("原始目錄不存在!");
			return false;
		} else if (!sourceDir.isDirectory()) {
			System.out.println("源不是目錄!");
			return false;
		}
		//自動添加文件分隔符
		if (!targetDirName.endsWith(File.separator)) {
			targetDirName = targetDirName + File.separator;
		}
		File targetDir = new File(targetDirName);
		if (targetDir.exists()) {//目標文件夾存在,
			if (isOverlay) {//是否覆蓋
				System.out.println("目錄已存在,準備刪除它!");
				if (!deleteFileOrDir(targetDirName)) {
					System.out.println("刪除已存在目錄失敗!");
				}
			} else {
				System.out.println("目錄已存在!");
				return false;
			}
		} else {// 創建目標目錄
			System.out.println("該目錄不存在,正在創建!");
			if (!targetDir.mkdirs()) {
				System.out.println("創建目標目錄失敗!");
				return false;
			}
		}
		boolean flag = true;
		//移動原目錄下的文件和子目錄到目標目錄下
		File[] files = sourceDir.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].isFile()) {// 移動子文件
				//構造移動後新生成的文件路徑
				flag = moveFile(files[i].getAbsolutePath(),
						targetDirName + files[i].getName(), isOverlay);
				if (!flag) {
					break;
				}
			}
			else if (files[i].isDirectory()) {// 移動子目錄
				flag = moveDir(files[i].getAbsolutePath(), targetDirName
						+ files[i].getName(), isOverlay);
				if (!flag) {
					break;
				}
			}
		}
		if (!flag) {
			System.out.println("目錄移動失敗!");
			return false;
		}
		// 刪除原目錄
		if (deleteDir(sourceDirName)) {
			System.out.println("目錄移動成功!");
			return true;
		} else {
			System.out.println("目錄移動失敗!");
			return false;
		}
	}

	
	/***-----------6.列舉文件---------***/
	
	/**
	 * 打印指定目錄的目錄結構
	 * @param dirName 指定目錄
	 * @param deep 深度,實現縮進打印
	 */
	public static void getAllFiles(String dirName, int deep) {
		//如果dir不以文件分隔符結尾,自動添加文件分隔符。
		if (!dirName.endsWith(File.separator)) {
			dirName = dirName + File.separator;
		}
		File dirFile = new File(dirName);
		//文件不存在,或不是目錄,則退出
		if (!dirFile.exists() || (!dirFile.isDirectory())) {
			System.out.println("找不到指定目錄");
			return;
		}
		//列出目錄下所有文件(包括子目錄)
		File[] fileArray = dirFile.listFiles();
		for (int i = 0; i < fileArray.length; i++) {
			if (fileArray[i].isFile()) {
				// 只打印文件名,而非完整路徑
				print(deep, fileArray[i].getName());
			} else if (fileArray[i].isDirectory()) {
				print(deep, fileArray[i].getName());//目錄
				getAllFiles(fileArray[i].getAbsolutePath(), deep + 1);
			}
		}
	}

	/**
	 * 實現層次縮進打印目錄結構
	 * @param deep 深度
	 * @param msg 消息
	 */
	private static void print(int deep, String msg) {
		for (int i = 1; i <= deep; i++)
			System.out.print("   ");
		System.out.println(msg);
	}
	
	
	/***-----------7.讀取文件---------***/
	
	/**1. 按字節讀取文件,常用於讀二進制文件,如圖片、聲音、影像文件等*/
	
	/**
	 * 1.1 按字節讀取文件, 一次讀取一個字節   
	 * @param fileName 文件路徑名
	 */
    public static void readFileByByte(String fileName) {
        File file = new File(fileName);
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            int tempbyte;
            //一次讀取一個字節的方式
            while ((tempbyte = in.read()) != -1) {
                System.out.write(tempbyte);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                }
            }
        }
    }

	/**
	 * 1.2 按字節讀取文件, 一次讀取多個字節
	 * @param fileName 文件路徑名
	 */
    public static void readFileByBytes(String fileName) {
        File file = new File(fileName);
        FileInputStream in = null;
        try {
        	in = new FileInputStream(file);
            // 一次讀取多個字節的方式
            byte[] tempbytes = new byte[100];
            int byteread = 0;
            in = new FileInputStream(fileName);
            // 讀入多個字節到字節數組中,byteread爲一次讀入的字節數
            while ((byteread = in.read(tempbytes)) != -1) {
                System.out.write(tempbytes, 0, byteread);
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                }
            }
        }
    }
    
    
    /**2. 以字符爲單位讀取文件,常用於讀文本,數字等類型文件*/
    
    /**
     *  2.1 以字符爲單位讀取文件,一次讀取一個字符
     * @param fileName 文件路徑名
     */
    public static void readFileByChar(String fileName) {
        File file = new File(fileName);
        Reader reader = null;
        try {
            reader = new InputStreamReader(new FileInputStream(file));
            int tempchar;
            //一次讀一個字符
            while ((tempchar = reader.read()) != -1) {
                // 對於windows下,\r\n這兩個字符在一起時,表示一個換行。
                // 但如果這兩個字符分開顯示時,會換兩次行。
                // 因此,屏蔽掉\r,或者屏蔽\n。否則,將會多出很多空行。
                if (((char) tempchar) != '\r') {
                    System.out.print((char) tempchar);
                }
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
    }
    
    /**
     *  2.2 以字符爲單位讀取文件,一次讀取多個字符
     * @param fileName 文件路徑名
     */
    public static void readFileByChars(String fileName) {
        File file = new File(fileName);
        Reader reader = null;
        try {
        	reader = new InputStreamReader(new FileInputStream(file));
            // 一次讀多個字符
            char[] tempchars = new char[30];
            int charread = 0;
            reader = new InputStreamReader(new FileInputStream(fileName));
            // 讀入多個字符到字符數組中,charread爲一次讀取字符數
            while ((charread = reader.read(tempchars)) != -1) {
                // 同樣屏蔽掉\r不顯示
                if ((charread == tempchars.length)
                        && (tempchars[tempchars.length - 1] != '\r')) {
                    System.out.print(tempchars);
                } else {
                    for (int i = 0; i < charread; i++) {
                        if (tempchars[i] == '\r') {
                            continue;
                        } else {
                            System.out.print(tempchars[i]);
                        }
                    }
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
    }

    /**
     * 3. 以行爲單位讀取文件,常用於讀面向行的格式化文件
     * @param fileName 文件路徑名
     */
    public static void readFileByLines(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            int line = 1;
            // 一次讀入一行,直到讀入null爲文件結束
            while ((tempString = reader.readLine()) != null) {
                // 顯示行號
                System.out.println("line " + line + ": " + tempString);
                line++;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
    }

    /**
     * 4. 隨機讀取文件內容
     * @param fileName 文件路徑名
     */
    public static void readFileByRandomAccess(String fileName) {
        RandomAccessFile randomFile = null;
        try {
            // 打開一個隨機訪問文件流,按只讀方式
            randomFile = new RandomAccessFile(fileName, "r");
            // 文件長度,字節數
            long fileLength = randomFile.length();
            // 讀文件的起始位置
            Random r=new Random();
            //隨機初始讀取位置
            int beginIndex=r.nextInt((int)fileLength);
            // 將讀文件的開始位置移到beginIndex位置。
            randomFile.seek(beginIndex);
            byte[] bytes = new byte[10];
            int byteread = 0;
            // 一次讀10個字節,如果文件內容不足10個字節,則讀剩下的字節。
            // 將一次讀取的字節數賦給byteread
            while ((byteread = randomFile.read(bytes)) != -1) {
                System.out.write(bytes, 0, byteread);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (randomFile != null) {
                try {
                    randomFile.close();
                } catch (IOException e1) {
                }
            }
        }
    }
}

發佈了33 篇原創文章 · 獲贊 14 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章