首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Apache Commons IO 文件操作工具類封裝:複製、刪除、讀寫、追加

     編輯:Java 程式設計入門

前言

Apache Commons IO 是 Java 文件操作的標準庫,提供了線程安全、異常處理完善的高級 API。本文封裝一個生產就緒的 FileUtil 工具類,整合複製、刪除、字符串寫入、內容讀取、追加寫入等常用功能,並針對編碼、目錄自動創建、資源釋放進行增強。

Maven 依賴

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.15.1</version> <!-- 檢查最新版本 -->
</dependency>

完整工具類實現

package com.example.util;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.Charsets;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class FileUtil {

    // ========== 1. 複製文件/目錄 ==========
    /**
     * 複製文件或目錄到目標文件夾
     * @param srcPath 源路徑(文件或目錄)
     * @param destDir 目標文件夾(必須存在或可創建)
     */
    public static void copy(String srcPath, String destDir) throws IOException {
        File src = new File(srcPath);
        File dest = new File(destDir);
        
        if (!dest.exists()) {
            if (!dest.mkdirs()) throw new IOException("無法創建目標目錄:" + destDir);
        }
        
        if (src.isDirectory()) {
            FileUtils.copyDirectoryToDirectory(src, dest);
        } else if (src.isFile()) {
            FileUtils.copyFileToDirectory(src, dest);
        } else {
            throw new FileNotFoundException("源路徑不存在:" + srcPath);
        }
    }

    // ========== 2. 刪除文件/目錄 ==========
    /**
     * 遞歸刪除文件或目錄(目錄非空也可刪除)
     */
    public static void delete(String path) throws IOException {
        File target = new File(path);
        if (target.isDirectory()) {
            FileUtils.deleteDirectory(target);
        } else if (target.isFile()) {
            if (!target.delete()) {
                throw new IOException("文件刪除失敗:" + path);
            }
        }
    }

    // ========== 3. 字符串寫入文件(自動創建父目錄) ==========
    /**
     * 將字符串寫入文件,指定編碼(默認 UTF-8)
     * @return true 成功
     */
    public static boolean writeString(String content, String filePath, String encoding) throws IOException {
        File file = new File(filePath);
        // 自動創建父目錄
        File parent = file.getParentFile();
        if (parent != null && !parent.exists() && !parent.mkdirs()) {
            throw new IOException("無法創建父目錄:" + parent);
        }
        
        FileUtils.writeStringToFile(file, content, Charset.forName(encoding), false);
        return true;
    }
    
    /** 默認 UTF-8 重載 */
    public static boolean writeString(String content, String filePath) throws IOException {
        return writeString(content, filePath, StandardCharsets.UTF_8.name());
    }

    // ========== 4. 讀取文件所有行 ==========
    /**
     * 讀取文件每行內容到 List,自動處理編碼
     * @return 列表,文件不存在返回空列表
     */
    public static List readLines(String filePath, String encoding) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) return new ArrayList<>();
        
        return FileUtils.readLines(file, Charset.forName(encoding));
    }
    
    /** 默認 UTF-8 重載 */
    public static List readLines(String filePath) throws IOException {
        return readLines(filePath, StandardCharsets.UTF_8.name());
    }

    // ========== 5. 追加內容到文件 ==========
    /**
     * 追加多行內容到文件末尾
     */
    public static void appendLines(String filePath, List lines, String encoding) throws IOException {
        File file = new File(filePath);
        File parent = file.getParentFile();
        if (parent != null && !parent.exists() && !parent.mkdirs()) {
            throw new IOException("無法創建父目錄:" + parent);
        }
        
        FileUtils.writeLines(file, Charset.forName(encoding), lines, null, true); // true = append
    }
    
    /** 默認 UTF-8、換行符 \n 重載 */
    public static void appendLines(String filePath, List lines) throws IOException {
        appendLines(filePath, lines, StandardCharsets.UTF_8.name());
    }

    // ========== 6. 進階:大文件分行處理(避免 OOM) ==========
    /**
     * 逐行處理大文件,配合 LineProcessor 回調
     */
    public static void processLargeFile(String filePath, LineProcessor processor) throws IOException {
        File file = new File(filePath);
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
            
            String line;
            int lineNum = 0;
            while ((line = reader.readLine()) != null) {
                processor.process(lineNum++, line);
            }
        }
    }
    
    @FunctionalInterface
    public interface LineProcessor {
        void process(int lineNumber, String line) throws IOException;
    }

    // ========== 測試主方法 ==========
    public static void main(String[] args) throws IOException {
        String testDir = "D:/fileutil_test";
        String testFile = testDir + "/demo.txt";
        
        // 1. 寫入
        writeString("第一行\n第二行\n第三行", testFile);
        System.out.println("寫入完成");
        
        // 2. 讀取
        List lines = readLines(testFile);
        System.out.println("讀取內容:" + lines);
        
        // 3. 追加
        appendLines(testFile, List.of("第四行", "第五行"));
        System.out.println("追加完成,最新內容:" + readLines(testFile));
        
        // 4. 複製
        copy(testFile, testDir + "/backup");
        System.out.println("複製完成");
        
        // 5. 大文件處理示例
        processLargeFile(testFile, (num, line) -> 
            System.out.printf("Line %d: %s%n", num, line));
        
        // 6. 清理
        delete(testDir);
        System.out.println("測試目錄已清理");
    }
}

核心優化點解析

1. 編碼顯式指定,杜絕亂碼

所有讀寫方法強制要求 Charset 參數,默認提供 UTF-8 重載。避免使用平台默認編碼(FileReader 等)導致跨平台亂碼。

2. 目錄自動創建

寫入/追加前檢查父目錄,不存在則 mkdirs(),消除 "No such file or directory" 異常。

3. 資源安全釋放

內部使用 Commons IO 的 FileUtils,其底層已正確處理流關閉;大文件處理方法採用 try-with-resources 確保 BufferedReader 關閉。

4. 靈活的大文件處理

提供 LineProcessor 函數式接口,支持流式逐行處理 GB 級文件,不載入內存。

常見問題與避坑指南

問題原因解決
中文亂碼未指定編碼,Windows 默認 GBK,Linux 默認 UTF-8統一指定 StandardCharsets.UTF_8
大文件 OOMreadLines() 一次性載入所有行使用 processLargeFile() 流式處理
追加覆蓋writeLines 最後參數 append 為 false調用 appendLines() 或傳 true
複製失敗目標目錄不存在工具類內部自動 mkdirs()

總結

本工具類基於 Apache Commons IO 2.x 封裝,提供了線程安全、編碼安全、資源安全的文件操作 API。實際項目中可直接引入,並根據需要擴展:MD5 校驗、壓縮/解壓、文件監聽等功能。記住:永遠顯式指定 UTF-8 編碼,大文件必須流式處理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved