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

Java 創建隱藏文件的跨平台實現方案

     編輯:Java 相關知識

Java 早期版本(JDK 6 及之前)無原生 API 設置文件隱藏屬性,常見做法是調用系統命令(Windows `attrib +H`、Unix/Linux 以 `.` 開頭命名)。JDK 7 引入 java.nio.file.attribute.FileAttribute 與 Files.setAttribute,實現了跨平台的隱藏文件創建。本文對比兩種方案並給出最佳實踐代碼。

方案對比

維度Runtime.exec 系統命令NIO.2 Files.setAttribute (JDK 7+)
跨平台需區分 OS 編寫不同命令統一 API,底層自動映射
權限要求需命令執行權限,受安全管理器限制僅需文件系統寫入權限
錯誤處理進程返回碼、輸出流解析麻煩標準 IOException 體系
性能啟動進程開銷大原生系統調用,輕量
適用版本JDK 1.0+JDK 7+

現代標準寫法(推薦)

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;

public class HiddenFileCreator {

    /**
     * 跨平台創建隱藏文件
     * Windows: 設置 dos:hidden 屬性
     * Unix/Linux/macOS: 文件名以 '.' 開頭 (約定俗成),或設置 posix:hidden (極少數文件系統支持)
     */
    public static Path createHiddenFile(String dirPath, String fileName) throws IOException {
        Path dir = Paths.get(dirPath);
        if (!Files.exists(dir)) {
            Files.createDirectories(dir);
        }

        // Unix/Linux/macOS: 隱藏文件約定為以 '.' 開頭
        String actualName = isWindows() ? fileName : "." + fileName;
        Path filePath = dir.resolve(actualName);

        // 創建空文件
        Files.createFile(filePath);

        // Windows 額外設置 hidden 屬性 (雙重保險)
        if (isWindows()) {
            try {
                Files.setAttribute(filePath, "dos:hidden", true);
            } catch (UnsupportedOperationException | IOException e) {
                // 文件系統不支持 dos 屬性 (如 FAT32 某些情況),忽略
            }
        }
        return filePath;
    }

    private static boolean isWindows() {
        String os = System.getProperty("os.name").toLowerCase();
        return os.contains("win");
    }

    // 測試
    public static void main(String[] args) throws IOException {
        Path hidden = createHiddenFile("D:/test", "secret.data");
        System.out.println("隱藏文件已創建: " + hidden.toAbsolutePath());
        System.out.println("是否隱藏(Windows): " + Files.isHidden(hidden)); // JDK 7+ 原生支持
    }
}

舊版本兼容方案(JDK 6 或受限環境)

public class LegacyHiddenFile {
    public static void createHiddenFile(String absolutePath) throws IOException {
        File file = new File(absolutePath);
        if (file.exists()) file.delete();
        file.createNewFile();

        if (isWindows()) {
            // Windows: attrib +H
            String cmd = "attrib +H \"" + file.getAbsolutePath() + "\"";
            Process p = Runtime.getRuntime().exec(cmd);
            try { p.waitFor(); } catch (InterruptedException ignored) {}
        } else {
            // Unix: 重命名為 .開頭
            File hidden = new File(file.getParent(), "." + file.getName());
            file.renameTo(hidden);
        }
    }
}

驗證文件是否隱藏

// JDK 7+ 統一 API
boolean hidden = Files.isHidden(path); 

// 手動檢查 (跨版本)
public static boolean isHidden(File file) {
    if (isWindows()) {
        try {
            Process p = Runtime.getRuntime().exec("attrib \"" + file.getAbsolutePath() + "\"");
            p.waitFor();
            Scanner sc = new Scanner(p.getInputStream());
            return sc.nextLine().contains("H");
        } catch (Exception e) { return false; }
    } else {
        return file.getName().startsWith(".");
    }
}

注意事項

  • Unix 隱藏只是命名約定:`ls -a` 仍可見,非文件系統屬性
  • Windows `dos:hidden` 需 NTFS/FAT32 支持:部分網絡共享、虛擬文件系統可能不支持
  • 不要用於安全機制:隱藏文件極易被查看,敏感數據應加密存儲
  • JDK 7+ `Files.isHidden()` 已封裝跨平台邏輯:優先使用

總結

現代 Java 應用強烈建議基於 NIO.2 (`Files.setAttribute`, `Files.isHidden`) 實現隱藏文件創建與檢測,代碼簡潔、跨平台、異常處理規範。僅在維護極老舊系統(JDK 6)時才考慮 `Runtime.exec` 方案,並做好 OS 判斷與錯誤容忍。

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