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

Java 常用工具類:文件操作工具類 FileUtil 詳解

     編輯:Java 相關知識

前言

在 Java 專案開發中,文件操作是高頻需求。雖然 JDK 提供了 java.io 與 java.nio 套件,但針對業務場景封裝一個通用的工具類,能大幅減少樣板代碼,提升開發效率。本文介紹一個實用的 FileUtil 類,涵蓋文件/目錄複製、刪除、儲存、獲取文件名與副檔名等核心功能。

核心功能設計

1. 文件與目錄遞歸複製

copy(File inputFile, File outputFile, boolean isOverWrite) 方法支援單文件與整個目錄樹的複製。內部透過私有方法 copyPri 遞歸處理子目錄,copySimpleFile 以 1KB 緩衝區進行流式讀寫,確保大文件不會導致記憶體溢出。

2. 安全刪除文件/目錄

delete(File file) 封裝了遞歸刪除邏輯。先刪除子文件/子目錄,最後刪除自身。若刪除失敗會拋出 RuntimeException,方便上層捕獲處理。

3. 文件儲存支援多種來源

提供兩個 save 重載:

  • save(byte[] content, File file):直接寫入位元組陣列。
  • save(InputStream streamIn, File file):從輸入流讀取,使用 8KB 緩衝區,自動建立父目錄。

4. 路徑解析工具方法

  • getFilenameExtension(String path):提取副檔名(不含點號)。
  • getFilename(String path):提取完整文件名(含副檔名)。

兩者均處理 null 輸入與路徑分隔符兼容性。

代碼示例

package com.itjh.javaUtil;

import java.io.*;

public class FileUtil {
    private static final String FOLDER_SEPARATOR = "/";
    private static final char EXTENSION_SEPARATOR = '.';

    public static void copy(File inputFile, File outputFile, boolean isOverWrite) throws IOException {
        if (!inputFile.exists()) {
            throw new RuntimeException(inputFile.getPath() + " 源路徑不存在!");
        }
        copyPri(inputFile, outputFile, isOverWrite);
    }

    private static void copyPri(File inputFile, File outputFile, boolean isOverWrite) throws IOException {
        if (inputFile.isFile()) {
            copySimpleFile(inputFile, outputFile, isOverWrite);
        } else {
            if (!outputFile.exists()) outputFile.mkdir();
            for (File child : inputFile.listFiles()) {
                copy(child, new File(outputFile.getPath() + "/" + child.getName()), isOverWrite);
            }
        }
    }

    private static void copySimpleFile(File inputFile, File outputFile, boolean isOverWrite) throws IOException {
        if (outputFile.exists()) {
            if (isOverWrite) {
                if (!outputFile.delete()) throw new RuntimeException(outputFile.getPath() + " 無法覆蓋!");
            } else return;
        }
        try (InputStream in = new FileInputStream(inputFile);
             OutputStream out = new FileOutputStream(outputFile)) {
            byte[] buffer = new byte[1024];
            int read;
            while ((read = in.read(buffer)) != -1) out.write(buffer, 0, read);
        }
    }

    public static void delete(File file) { deleteFile(file); }

    private static void deleteFile(File file) {
        if (file == null || !file.exists()) return;
        if (!file.isDirectory()) {
            if (!file.delete()) throw new RuntimeException(file.getPath() + " 刪除失敗!");
            return;
        }
        for (File child : file.listFiles()) deleteFile(child);
        file.delete();
    }

    public static String getFilenameExtension(String path) {
        if (path == null) return null;
        int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
        if (extIndex == -1) return null;
        int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
        if (folderIndex > extIndex) return null;
        return path.substring(extIndex + 1);
    }

    public static String getFilename(String path) {
        if (path == null) return null;
        int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
        return (separatorIndex != -1) ? path.substring(separatorIndex + 1) : path;
    }

    public static void save(byte[] content, File file) throws IOException {
        if (file == null) throw new RuntimeException("儲存文件不能為空");
        if (content == null) throw new RuntimeException("文件流不能為空");
        save(new ByteArrayInputStream(content), file);
    }

    public static void save(InputStream streamIn, File file) throws IOException {
        if (file == null) throw new RuntimeException("儲存文件不能為空");
        if (streamIn == null) throw new RuntimeException("文件流不能為空");
        if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
        try (OutputStream streamOut = new FileOutputStream(file)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = streamIn.read(buffer)) != -1) streamOut.write(buffer, 0, bytesRead);
        } finally {
            streamIn.close();
        }
    }
}

使用建議

  • 大文件操作建議配合 NIO2 (Files.copy、Files.walkFileTree) 以獲得更好性能。
  • 生產環境中刪除操作建議加入日誌記錄與權限校驗。
  • 工具類方法均為 static,無狀態,線程安全。

總結

這個 FileUtil 類將常見文件操作封裝為靜態方法,代碼結構清晰、異常處理明確,適合直接集成到專案公共模組中。後續可擴展支援壓縮解壓、MD5 校驗等功能,構建更完整的文件處理工具箱。

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