在處理文字檔案時,編碼格式不一致常導致亂碼問題。本文提供一個完整的 C# 解決方案,能夠遞迴掃描資料夾,自動偵測每個文字檔是否為 UTF-8 編碼,並示範如何讀取非 UTF-8 檔案的內容。
UTF-8 採用變長編碼,根據 Unicode 碼位範圍決定位元組長度:
IsUTF8 方法逐位元組檢查位元模式,確認是否符合上述規則。若檔案全為 ASCII 則判定為非 UTF-8(避免誤判純 ASCII 檔)。
using System;
using System.IO;
using System.Text;
public class EncodingDetector
{
///
/// 遞迴掃描資料夾,找出非 UTF-8 編碼的文字檔
///
public void FindNonUtf8Files(string rootPath)
{
DirectoryInfo folder = new DirectoryInfo(rootPath);
// 遞迴處理子資料夾
foreach (DirectoryInfo subFolder in folder.GetDirectories())
{
FindNonUtf8Files(subFolder.FullName);
}
// 處理當前資料夾下的檔案
foreach (FileInfo file in folder.GetFiles())
{
if (IsTextFile(file.Extension.ToLower()))
{
ProcessFile(file);
}
}
}
private bool IsTextFile(string extension)
{
// 可依需求擴充副檔名清單
string[] textExtensions = { ".txt", ".cs", ".xml", ".json", ".config", ".log", ".ini" };
return Array.Exists(textExtensions, ext => ext == extension);
}
private void ProcessFile(FileInfo file)
{
using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
bool isUtf8 = IsUTF8(fs);
if (!isUtf8)
{
Console.WriteLine($"發現非 UTF-8 檔案: {file.FullName}");
// 示範以預設編碼(系統預設)讀取並轉為 UTF-8
string content = File.ReadAllText(file.FullName, Encoding.Default);
File.WriteAllText(file.FullName, content, Encoding.UTF8);
Console.WriteLine("已轉換為 UTF-8 編碼");
}
}
}
///
/// 判斷檔案流是否為有效的 UTF-8 編碼
///
private static bool IsUTF8(FileStream stream)
{
int byteCount = 0; // 當前字元預期的後續位元組數
bool allAscii = true; // 是否全為 ASCII 字元
long length = stream.Length;
for (long i = 0; i < length; i++)
{
byte chr = (byte)stream.ReadByte();
// 檢查是否為非 ASCII 字元
if ((chr & 0x80) != 0)
allAscii = false;
if (byteCount == 0)
{
// 判斷起始位元組
if (chr >= 0x80)
{
// 計算後續位元組數量
do
{
chr <<= 1;
byteCount++;
} while ((chr & 0x80) != 0);
byteCount--; // 扣除起始位元組本身
// 無效的起始位元組模式
if (byteCount == 0)
return false;
}
}
else
{
// 檢查後續位元組是否符合 10xxxxxx 格式
if ((chr & 0xC0) != 0x80)
return false;
byteCount--;
}
}
// 位元組數未歸零表示截斷
if (byteCount > 0)
return false;
// 純 ASCII 檔案不視為 UTF-8(視需求調整)
if (allAscii)
return false;
return true;
}
}
var detector = new EncodingDetector();
detector.FindNonUtf8Files(@"C:\MyProject\SourceCode");
Ude.NetStandard 等函式庫支援更多編碼偵測本範例展示了不依賴第三方套件、純 .NET Framework 實作 UTF-8 偵測的核心邏輯。理解 UTF-8 位元組結構有助於處理各種編碼相容性問題,實務上建議搭配 BOM 檢查與抽樣讀取以提升效能與準確度。