本文彙總 C# 開發中高頻使用的實用技巧,涵蓋檔案版本資訊、檔案屬性操作、字串格式化、檔案 IO、對話框使用等,代碼可直接複製應用。
using System.Diagnostics;
public static string GetFileVersion(string filePath)
{
if (!File.Exists(filePath)) return null;
FileVersionInfo info = FileVersionInfo.GetVersionInfo(filePath);
return $"版本: {info.FileVersion}\n" +
$"產品: {info.ProductName}\n" +
$"公司: {info.CompanyName}\n" +
$"著作權: {info.LegalCopyright}\n" +
$"描述: {info.FileDescription}";
}
// 使用
string version = GetFileVersion(@"D:\MyApp\MyLib.dll");
public static void ForceCopy(string source, string destination)
{
if (File.Exists(destination))
{
FileInfo fi = new FileInfo(destination);
// 移除唯讀屬性
if ((fi.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
fi.Attributes = FileAttributes.Normal;
}
File.Delete(destination);
}
File.Copy(source, destination, true); // true = 允許覆寫
}
string str = "12345";
int number = int.TryParse(str, out int result) ? result : 0;
// 或
int number2 = Convert.ToInt32(str); // 例外較多,建議 TryParse
string code = "42";
// 左補零至 6 位: "000042"
string padded = code.PadLeft(6, '0');
// 右補空格至 30 字元
string line = "項目名稱".PadRight(30, ' ');
int year = 2024, month = 1, day = 15;
decimal price = 1234.56m;
// 字串插值 (C# 6+)
string s1 = $"{year:D4}/{month:D2}/{day:D2} 價格: {price:C2}";
// 複合格式
string s2 = string.Format("{0:D4}/{1:D2}/{2:D2} 價格: {3:C2}", year, month, day, price);
// 自訂日期格式
string s3 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
public static IEnumerable ReadLinesLazy(string path)
{
if (!File.Exists(path)) yield break;
using (var reader = new StreamReader(path, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
yield return line;
}
}
// 使用
foreach (string line in ReadLinesLazy("log.txt"))
{
Console.WriteLine(line);
}
public static void WriteLines(string path, IEnumerable lines)
{
using (var writer = new StreamWriter(path, false, Encoding.UTF8)) // false = 覆寫
{
foreach (string line in lines)
writer.WriteLine(line);
}
}
// 追加模式
public static void AppendLine(string path, string line)
{
using (var writer = new StreamWriter(path, true, Encoding.UTF8)) // true = 追加
{
writer.WriteLine(line);
}
}
bool fileExists = File.Exists(@"C:\Data\config.json");
bool dirExists = Directory.Exists(@"C:\Data\Backups");
// 確保目錄存在
string dir = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir); // 遞迴建立所有父目錄
using System.Windows.Forms;
public static string ShowOpenFileDialog(string initialDir = null, string filter = "所有檔案 (*.*)|*.*")
{
using (var dialog = new OpenFileDialog())
{
dialog.InitialDirectory = initialDir ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
dialog.Filter = filter;
dialog.FilterIndex = 1;
dialog.RestoreDirectory = true;
dialog.Multiselect = false;
dialog.Title = "請選擇檔案";
return dialog.ShowDialog() == DialogResult.OK ? dialog.FileName : null;
}
}
// 多選
public static string[] ShowOpenFilesDialog()
{
using (var dialog = new OpenFileDialog { Multiselect = true })
{
return dialog.ShowDialog() == DialogResult.OK ? dialog.FileNames : Array.Empty();
}
}
public static string ShowFolderDialog(string description = "請選擇資料夾")
{
using (var dialog = new FolderBrowserDialog())
{
dialog.Description = description;
dialog.RootFolder = Environment.SpecialFolder.MyComputer;
dialog.ShowNewFolderButton = true;
return dialog.ShowDialog() == DialogResult.OK ? dialog.SelectedPath : null;
}
}
public static async Task CopyWithProgressAsync(string source, string dest, IProgress progress, CancellationToken ct = default)
{
const int bufferSize = 81920; // 80KB
long totalBytes = new FileInfo(source).Length;
long copiedBytes = 0;
using (var srcStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true))
using (var dstStream = new FileStream(dest, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, true))
{
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = await srcStream.ReadAsync(buffer, ct)) > 0)
{
await dstStream.WriteAsync(buffer.AsMemory(0, bytesRead), ct);
copiedBytes += bytesRead;
progress?.Report((double)copiedBytes / totalBytes * 100);
}
}
}
// 使用
var progress = new Progress(p => Console.WriteLine($"進度: {p:F1}%"));
await CopyWithProgressAsync("big.iso", "copy.iso", progress);
string path = @"C:\Projects\MyApp\bin\Debug\app.exe";
Path.GetFileName(path); // "app.exe"
Path.GetFileNameWithoutExtension(path); // "app"
Path.GetExtension(path); // ".exe"
Path.GetDirectoryName(path); // "C:\Projects\MyApp\bin\Debug"
Path.GetFullPath("..\\config.json"); // 解析相對路徑
Path.Combine("C:\\Data", "logs", "app.log"); // 安全組合路徑
Path.ChangeExtension(path, ".bak"); // "app.bak"
Path.GetRandomFileName(); // 產生隨機檔名 (如 "abc123.tmp")
Path.GetTempFileName(); // 建立暫存檔並回傳路徑
掌握這些基礎 API 能解決 80% 的檔案/字串/對話框需求。現代專案請注意:
System.Text.Json 處理結構化資料,而非手動解析文字檔async/await + FileStream 避免阻塞 UIPath 類別,勿字串拼接Encoding.UTF8,避免預設編碼差異