.NET BCL Series | File

2022-06-22

筆記 .NET Base Class Library 各式基礎函式庫的使用原理與技巧,讓開發 .NET 程式自然且流暢 🙂

logo

使用範例

在桌面建立檔案並寫入文字內容。

var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var filePath = Path.Combine(desktop, $"{Guid.NewGuid()}.txt");

File.WriteAllText(filePath, $"{Hello World}\n{DateTime.Now}");

建立資料夾,並以今日日期命名。

var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var filePath = Path.Combine(desktop, $"{DateTime.Now.ToString("yyyy-MM-dd")}");
Directory.CreateDirectory(filePath);

列出資料夾中的所有檔案,顯示檔案名稱、建立日期與大小。

foreach (var file in Directory.GetFiles(Path.Combine(desktop, "sample")))
{
    var finfo = new FileInfo(file);
    Console.WriteLine($"{finfo.FullName}\n{finfo.CreationTime}\n{finfo.Length}");
}

從網路上下載檔案,並儲存於桌面。

var fileUrl = "https://mopsfin.twse.com.tw/opendata/t187ap03_L.csv";
var filePath = Path.Combine(desktop, "data.csv");
var client = new WebClient();

// Sync
client.DownloadFile(fileUrl, filePath);

// Async
filePath = Path.Combine(desktop, "dataAsync.csv");
await client.DownloadFileTaskAsync(new Uri(fileUrl), filePath);

client.Dispose();

將內容以 Base64 編碼後再儲存成檔案。

var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var filePath = Path.Combine(desktop, $"{Guid.NewGuid()}.txt");
var text = Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes("hello world"));

File.WriteAllText(filePath $"{text.ToString()}");

重新命名檔案以及搬移檔案到新的路徑。

var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var filePath = Path.Combine(desktop, "file.txt");
var fInfo = new FileInfo(filePath);

var renameOrNewPath = Path.Combine(desktop, "new.txt");
if (File.Exists(renameOrNewPath))
{
    File.Delete(renameOrNewPath);
}
fInfo.MoveTo(renameOrNewPath);

計算檔案的 SHA256。

必須要使用檔案的 Stream 作為參數,提供 SHA256 進行 ComputeHash

using System.Security.Cryptography;
var f = new FileInfo(@"C:\temp\1.txt");

using (SHA256 sha256 = SHA256.Create())
{
  using (FileStream fileStream = f.Open(FileMode.Open))
  {
    try
    {
        fileStream.Position = 0;
        byte[] hashes = sha256.ComputeHash(fileStream);
        string base64 = Convert.ToBase64String(hashes)};
        Console.Write($"{f.Name} {base64}");
        
        string hash = string.Empty;
        hash = String.Join("", hashes.Select(i => i.ToString("x2"))).ToUpper();
        Console.Write($"{f.Name} {hash}");
        // Value Same with PowerShell Get-FileHash

    }
    catch (IOException e)
    {
        Console.WriteLine($"I/O Exception: {e.Message}");
    }
    catch (UnauthorizedAccessException e)
    {
        Console.WriteLine($"Access Exception: {e.Message}");
    }
  }
}

專題探討

Path.ChangeExtension

可以用於改變檔案的副檔名。

var path = @"C:\temp\file.sdwh.txt";

Path.ChangeExtension(path, ".pdf")
// C:\temp\file.sdwh.pdf

Path.ChangeExtension(path, "pdf")
// C:\temp\file.sdwh.pdf

Path.ChangeExtension(path, "")
// C:\temp\file.sdwh.
// Remove extension but weired 😶

path = @"C:\temp\file";
Path.ChangeExtension(path, "pdf")
// C:\temp\file.pdf
// Add Extension to File 😏

path = @"C:\temp\";
Path.ChangeExtension(path, "pdf")
// C:\temp\.pdf
// Weired situation 😶

File vs FileInfo

File 是使用 Satatic Method 來進行 Exists, Delete, Copy 以及 Move 等處理。

FileInfo 則是將路徑當作引數的方式 new 物件並使用 Class Property 以及 Public Method 來進行Exists, Delete, Copy 以及 Move 等處理。

相同的 Directory 以及 DirectoryInfo 也是相同的關係,使用上無優劣,慣用即可。

FileSystemWatcher

可以用於監督作業系統中資料夾與檔案內容的變化,並以事件 Handler 的方式處理變化。

var watcher = new FileSystemWatcher
{
    Path = "C:\MonitoringFolder",
    NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName,
    Filter = "*.txt",
    IncludeSubdirectories = false,
    EnableRaisingEvents = true
};

watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);

Handler

private static void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine($"File Change: {e.FullPath} {e.ChangeType}");
}

private static void OnRenamed(object source, RenamedEventArgs e)
{
    Console.WriteLine($"File Rename From {e.OldFullPath} to {e.FullPath}");
}

WriteAllText vs WriteAllLines

WriteAllText
輸入字串,並且入檔案
WriteAllLines
輸入字串陣列,並寫入檔案
WriteAllBytes
輸入 Byte陣列,並寫入檔案
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var textPath = Path.Combine(desktop, "hello.txt");
File.WriteAllText(textPath, "Hello World\nYeah");
//Hello World
//Yeah

textPath = Path.Combine(desktop, "hello2.txt");
File.WriteAllLines(textPath, new List<string> { "Hello", "World", "Yeah" });
//Hello
//World
//Yeah
//

WriteAllBytes

可以搭配專案的 Resources 資源檔,達到建立 .dll, .exe 等檔案的效果。

建立 .NET 應用程式的資源檔 | learn.microsoft