.NET Framework 內建編碼轉換雖支援 Big5 與 GB2312 互轉,但在某些舊版系統或特殊需求下,仍需呼叫 Windows 核心函式 LCMapString 進行更精確的繁簡轉換。本文示範如何透過 P/Invoke 呼叫 kernel32.dll 實現目錄下所有文字檔的批次繁轉簡。
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
public class EncodeTool
{
[DllImport("kernel32.dll", EntryPoint = "LCMapStringA")]
public static extern int LCMapString(int Locale, int dwMapFlags, byte[] lpSrcStr, int cchSrc, byte[] lpDestStr, int cchDest);
const int LCMAP_SIMPLIFIED_CHINESE = 0x02000000;
const int LCMAP_TRADITIONAL_CHINESE = 0x04000000;
public static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("請指定來源目錄路徑!");
return;
}
string[] files = (args.Length == 2)
? Directory.GetFiles(args[0], args[1])
: Directory.GetFiles(args[0]);
string outputDir = Path.Combine(args[0], "conv");
if (!Directory.Exists(outputDir))
Directory.CreateDirectory(outputDir);
foreach (string file in files)
{
using (StreamReader sr = new StreamReader(file, Encoding.GetEncoding("big5")))
{
string content = sr.ReadToEnd();
string converted = ConvertString(content);
string destFile = Path.Combine(outputDir, Path.GetFileName(file));
using (StreamWriter sw = new StreamWriter(destFile, false, Encoding.GetEncoding("gb2312")))
{
sw.WriteLine(converted);
}
Console.WriteLine($"轉換 {file} 完成!");
}
}
}
public static string ConvertString(string input)
{
Encoding gb2312 = Encoding.GetEncoding(936); // GB2312 code page
byte[] src = gb2312.GetBytes(input);
byte[] dest = new byte[src.Length];
// 0x0804 = zh-CN locale
LCMapString(0x0804, LCMAP_SIMPLIFIED_CHINESE, src, -1, dest, src.Length);
return gb2312.GetString(dest);
}
}
Locale 設為 0x0804(中文簡體),dwMapFlags 使用 LCMAP_SIMPLIFIED_CHINESE 執行繁轉簡。kernel32.dll,跨平台專案請改用 .NET 內建 Encoding.Convert 或第三方庫(如 NConverter)。透過 P/Invoke 呼叫 Windows API,能以極少代碼實現高效能的繁簡轉換。若專案需跨平台,建議改用純 .NET 實作或成熟開源庫。