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

C# 實作自動偵測檔案是否為 UTF-8 編碼的完整範例

     編輯:關於C語言

前言

在處理文字檔案時,編碼格式不一致常導致亂碼問題。本文提供一個完整的 C# 解決方案,能夠遞迴掃描資料夾,自動偵測每個文字檔是否為 UTF-8 編碼,並示範如何讀取非 UTF-8 檔案的內容。

核心邏輯:UTF-8 編碼驗證演算法

UTF-8 採用變長編碼,根據 Unicode 碼位範圍決定位元組長度:

  • 1 位元組:0x00~0x7F(ASCII 相容區)
  • 2 位元組:0x80~0x7FF(110xxxxx 10xxxxxx)
  • 3 位元組:0x800~0xFFFF(1110xxxx 10xxxxxx 10xxxxxx)

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");

注意事項與擴充建議

  • 效能考量:大檔案僅讀取前幾 KB 即可判斷,可加入長度限制
  • BOM 偵測:可優先檢查 UTF-8 BOM (EF BB BF) 快速確認
  • 編碼轉換:轉碼前建議備份原檔,避免資料遺失
  • 擴充性:可整合 Ude.NetStandard 等函式庫支援更多編碼偵測

總結

本範例展示了不依賴第三方套件、純 .NET Framework 實作 UTF-8 偵測的核心邏輯。理解 UTF-8 位元組結構有助於處理各種編碼相容性問題,實務上建議搭配 BOM 檢查與抽樣讀取以提升效能與準確度。

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