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

C# 取得磁碟資訊完整指南:DriveInfo 類別與磁碟空間監控實作

     編輯:關於C#

前言

System.IO.DriveInfo 是 .NET Framework 2.0 引入的類別,提供存取磁碟機資訊的標準化方式,包括磁碟機類型、格式化式、總容量、可用空間、磁碟標籤等。本文完整解析 DriveInfo 用法、常見陷阱、跨平台差異與磁碟監控實作模式。

DriveInfo 核心屬性速查表

屬性型別說明單位/備註
Namestring磁碟機根目錄路徑如 "C:\\"
DriveTypeDriveType磁碟機類型枚舉Fixed、Removable、Network、CDRom、Ram、Unknown
DriveFormatstring檔案系統格式NTFS、FAT32、exFAT、ReFS
IsReadybool磁碟機是否就緒可讀取光碟機無媒體、網路磁碟離線時為 false
TotalSizelong總容量位元組
TotalFreeSpacelong總可用空間 (含配額限制)位元組
AvailableFreeSpacelong當前使用者可用空間位元組,受磁碟配額影響
VolumeLabelstring磁碟區標籤可讀寫 (需權限)
RootDirectoryDirectoryInfo根目錄資訊可進一步列舉檔案

基本用法範例

列舉所有磁碟機

using System;
using System.IO;

public static void ListAllDrives()
{
    DriveInfo[] drives = DriveInfo.GetDrives();
    
    Console.WriteLine($"{"磁碟機",-10} {"類型",-12} {"格式",-8} {"總容量",-15} {"可用空間",-15} {"標籤"}");
    Console.WriteLine(new string('-', 80));
    
    foreach (DriveInfo drive in drives)
    {
        Console.Write($"{drive.Name,-10} {drive.DriveType,-12} ");
        
        if (drive.IsReady)
        {
            Console.Write($"{drive.DriveFormat,-8} ");
            Console.Write($"{FormatBytes(drive.TotalSize),-15} ");
            Console.Write($"{FormatBytes(drive.AvailableFreeSpace),-15} ");
            Console.Write($"{drive.VolumeLabel}");
        }
        else
        {
            Console.Write("[未就緒/無媒體]");
        }
        Console.WriteLine();
    }
}

static string FormatBytes(long bytes)
{
    string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB" };
    int i = 0;
    double value = bytes;
    while (value >= 1024 && i < suffixes.Length - 1)
    {
        value /= 1024;
        i++;
    }
    return $"{value:0.##} {suffixes[i]}";
}

查詢特定磁碟機資訊

public static DriveInfo GetDriveInfo(string path)
{
    // 可傳入任意路徑,自動解析所在磁碟機
    DriveInfo drive = new DriveInfo(Path.GetPathRoot(path));
    
    if (!drive.IsReady)
        throw new IOException($"磁碟機 {drive.Name} 未就緒");
    
    return drive;
}

// 使用
var cDrive = GetDriveInfo(@"C:\");
Console.WriteLine($"C: 可用空間: {FormatBytes(cDrive.AvailableFreeSpace)}");

進階應用:磁碟空間監控服務

低磁碟空間預警監控器

using System;
using System.IO;
using System.Timers;

public class DiskSpaceMonitor : IDisposable
{
    private readonly Timer _timer;
    private readonly long _warningThresholdBytes;
    private readonly Action _alertAction;

    public DiskSpaceMonitor(string driveLetter, double warningThresholdGB, Action alertAction)
    {
        _warningThresholdBytes = (long)(warningThresholdGB * 1024 * 1024 * 1024);
        _alertAction = alertAction;
        
        _timer = new Timer(60000); // 每分鐘檢查一次
        _timer.Elapsed += CheckDiskSpace;
        _timer.AutoReset = true;
    }

    public void Start() => _timer.Start();
    public void Stop() => _timer.Stop();

    private void CheckDiskSpace(object sender, ElapsedEventArgs e)
    {
        try
        {
            DriveInfo drive = new DriveInfo(_timer.Tag?.ToString() ?? "C");
            if (!drive.IsReady) return;

            long freeSpace = drive.AvailableFreeSpace;
            if (freeSpace < _warningThresholdBytes)
            {
                double freeGB = freeSpace / (1024.0 * 1024 * 1024);
                _alertAction($"⚠️ 磁碟空間不足: {drive.Name} 剩餘 {freeGB:F2} GB (閾值: {_warningThresholdBytes / (1024.0*1024*1024):F1} GB)");
            }
        }
        catch (Exception ex)
        {
            _alertAction($"磁碟監控錯誤: {ex.Message}");
        }
    }

    public void Dispose()
    {
        _timer?.Stop();
        _timer?.Dispose();
    }
}

// 使用範例
var monitor = new DiskSpaceMonitor("C", 10, msg => 
{
    Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {msg}");
    // 可整合 Email、Slack、Windows 事件日誌等通知管道
});
monitor.Start();
// 程式結束時 monitor.Dispose();

取得資料夾所在磁碟剩餘空間 (跨平台相容)


public static long GetAvailableFreeSpace(string path)
{
    // .NET Core 3.0+ / .NET 5+ 支援 Unix 掛載點
    // Windows: DriveInfo 自動解析根目錄
    // Linux: 需解析 /proc/mounts 或使用 statvfs (P/Invoke)
    
    string root = Path.GetPathRoot(path);
    if (string.IsNullOrEmpty(root))
        root = Path.GetPathRoot(Path.GetFullPath(path));
    
    var drive = new DriveInfo(root);
    return drive.IsReady ? drive.AvailableFreeSpace : -1;
}

常見陷阱與解決方案

問題原因解決方案
TotalSize 回傳負數長度超過 Int32.MaxValue (2GB)屬性型別為 long,直接使用,勿轉 int
光碟機 IsReady 為 false無媒體或媒體損壞存取前必須檢查 IsReady,捕獲 IOException
網路磁碟機查詢緩慢/逾時網路延遲、離線非同步執行、設定逾時、快取結果
AvailableFreeSpace != TotalFreeSpace磁碟配額限制當前使用者依據業務需求選擇:配額環境用 AvailableFreeSpace
VolumeLabel 存取拒絕權限不足try-catch 包裹,或以管理員身分執行
單元測試難以模擬DriveInfo 為具體類別,無介面建立包裝介面 IDriveInfoService 進行抽象

跨平台考量 (.NET Core / .NET 5+)

  • Windows:完整支援所有屬性,磁碟機代號 (C:、D:)
  • Linux/macOS:掛載點路徑 (/, /home, /mnt/data),DriveType 多為 Fixed,Name 為掛載點路徑
  • Docker 容器:僅能看見容器掛載的卷,宿主機磁碟不可見

// 跨平台安全列舉
public static IEnumerable GetValidDrives()
{
    foreach (var drive in DriveInfo.GetDrives())
    {
        if (drive.IsReady)
            yield return drive;
        else
            Console.WriteLine($"跳過未就緒磁碟: {drive.Name} ({drive.DriveType})");
    }
}

單元測試友善設計:抽象介面


public interface IDiskSpaceService
{
    DriveInfoModel GetDriveInfo(string path);
    IEnumerable GetAllDrives();
}

public record DriveInfoModel
{
    public string Name { get; init; }
    public DriveType Type { get; init; }
    public string Format { get; init; }
    public long TotalSize { get; init; }
    public long FreeSpace { get; init; }
    public string Label { get; init; }
    public bool IsReady { get; init; }
}

public class DriveInfoService : IDiskSpaceService
{
    public DriveInfoModel GetDriveInfo(string path)
    {
        var drive = new DriveInfo(Path.GetPathRoot(path));
        return Map(drive);
    }

    public IEnumerable GetAllDrives()
    {
        return DriveInfo.GetDrives().Select(Map);
    }

    private DriveInfoModel Map(DriveInfo d) => new()
    {
        Name = d.Name,
        Type = d.DriveType,
        Format = d.DriveFormat,
        TotalSize = d.TotalSize,
        FreeSpace = d.AvailableFreeSpace,
        Label = d.VolumeLabel,
        IsReady = d.IsReady
    };
}

// 測試時可注入 Mock

總結

DriveInfo 是 .NET 存取磁碟資訊的標準 API,功能完整且跨平台支援良好。關鍵要點:

  1. 存取任何屬性前 必須檢查 IsReady
  2. 容量屬性為 long (64位),支援超大磁碟
  3. AvailableFreeSpace 反映實際可用空間 (含配額),TotalFreeSpace 為物理剩餘
  4. 生產環境建議 抽象介面 方便測試與替換
  5. 監控服務採用 輪詢 + 非同步 + 通知管道 架構

掌握這些核心概念,即可建立穩健的磁碟管理、監控與部署工具。

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