萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

Linux C 語言取得檔案系統資訊:statfs 系統呼叫實作完整代碼

使用 statfs() 系統呼叫取得檔案系統類型 (ext4/xfs/fat32/ntfs...)、總容量、可用容量、區塊大小等資訊,並封裝為可重複使用的函式庫,支援單位自動換算 (KB/MB/GB)。

核心資料結構


struct fileSystem_info {
    char fileSystem_format[8];        // 檔案系統類型字串
    char fileSystem_total_capacity[11]; // 總容量 (如 "120.50GB")
    char fileSystem_free_capacity[11];  // 可用容量
    char fileSystem_permissions[3];     // 權限 "rw"/"ro"
};

關鍵實作細節


int get_fileSystem_info(const char *path, struct fileSystem_info *fi) {
    struct statfs buf;
    if (statfs(path, &buf)) { perror("statfs"); return -1; }

    // 1. 判斷檔案系統類型 (f_type 魔術數字)
    switch (buf.f_type) {
        case 0xEF51: case 0xEF53: sprintf(fi->fileSystem_format, "EXT"); break;   // ext2/3/4
        case 0x58465342: sprintf(fi->fileSystem_format, "XFS"); break;            // XFS
        case 0x4D44: sprintf(fi->fileSystem_format, "FAT"); break;                // FAT16/32
        case 0x5346544E: sprintf(fi->fileSystem_format, "NTFS"); break;           // NTFS
        default: sprintf(fi->fileSystem_format, "UNKNOWN"); break;
    }

    // 2. 計算容量 (區塊數 × 區塊大小 → KB → 自動換算)
    unsigned long long total_blocks = buf.f_blocks;
    unsigned long long free_blocks  = buf.f_bfree;
    unsigned long block_size = buf.f_bsize;

    // kscale: 區塊數 × 區塊大小(bytes) → KB (四捨五入)
    auto kscale = [](unsigned long long blocks, unsigned long bsize) {
        return (blocks * bsize + 512) / 1024;
    };
    unsigned long long total_kb = kscale(total_blocks, block_size);
    unsigned long long free_kb  = kscale(free_blocks, block_size);

    // 3. 單位自動換算 (KB → MB → GB)
    auto convert = [](unsigned long long kb, char *dest) {
        if (kb >= 1024*1024) sprintf(dest, "%.2fGB", kb/1024.0/1024.0);
        else if (kb >= 1024) sprintf(dest, "%.2fMB", kb/1024.0);
        else sprintf(dest, "%.2fKB", (double)kb);
    };
    convert(total_kb, fi->fileSystem_total_capacity);
    convert(free_kb, fi->fileSystem_free_capacity);

    // 4. 權限判斷 (簡易:statfs 無直接權限欄位,可搭配 statvfs f_flag)
    sprintf(fi->fileSystem_permissions, "rw"); // 假設可讀寫

    return 0;
}

編譯與測試


gcc -o fsinfo fsinfo.c
./fsinfo /
# 輸出範例:
# EXT
# 115.32GB
# 42.17GB
# rw

注意事項

  • statfs 掛載點路徑 (如 /, /home, /mnt/data) 而非裝置節點。
  • 區塊大小 f_bsize 通常為 4096 (4KB),但部分檔案系統不同 (如 1024)。
  • 使用 unsigned long long 防止大容量磁碟 (>2TB) 乘法溢位。
  • 更完整資訊可改用 statvfs() (POSIX 標準) 取得 f_flag (ST_RDONLY, ST_NOSUID 等)。
copyright © 萬盛學電腦網 all rights reserved