相关库
.Net 8
编码识别: github.com/CharsetDetector/UTF-unknown
<PackageReference Include="UTF.Unknown" Version="2.5.1" />
代码
using UtfUnknown;
var dir_path = "D:\\Desktop\\新建文件夹2\\新建文件夹";
var dir_new_path = "D:\\Desktop\\新建文件夹2\\utf8_files";
var dir_rest_path = "D:\\Desktop\\新建文件夹2\\rest_files";
if (!Directory.Exists(dir_new_path)) Directory.CreateDirectory(dir_new_path);
if (!Directory.Exists(dir_rest_path)) Directory.CreateDirectory(dir_rest_path);
var file_path_list = Directory.EnumerateFiles(dir_path);
// 并行处理, 充分利用多核 CPU
file_path_list.AsParallel().ForAll(async file_path =>
{
var file_info = new FileInfo(file_path);
var file_new_path = Path.Combine(dir_new_path, file_info.Name);
var file_rest_path = Path.Combine(dir_rest_path, file_info.Name);
var file_bytes = await File.ReadAllBytesAsync(file_path);
// 截取文件的开头一点数据去分析,性能好, ( 整个文件分析,大文件太慢了. )
var file_type = CharsetDetector.DetectFromBytes(file_bytes[0..100]) ?? throw new Exception($"未知类型 {file_path}");
if (file_type.Detected.EncodingName == "gb18030")
{
// gb2312 -> c# 字符串 (utf-16)
var file_str = file_type.Detected.Encoding.GetString(file_bytes);
// utf-8,utf-8-bom,utf-16 有一点点差异 (具体自己查)
// WriteAllText 默认就是 UTF8 No BOM
await File.WriteAllTextAsync(file_new_path, file_str);
Console.WriteLine($"{file_info.Name} gb2312 -> utf8 完成");
// 如果事先就知道所有文件是 gb2312 编码,
// 可以直接调用解析, 无需 UtfUnknown 去识别. 性能更快
// 注册编码 写在 for 外面, 注册一次就行
// Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// 调用
// var str = Encoding.GetEncoding("gb18030").GetString(file_bytes);
}
else if (file_type.Detected.EncodingName == "utf-8")
{
File.Copy(file_path, file_new_path);
Console.WriteLine($"{file_info.Name} utf8 复制完成");
}
else
{
File.Copy(file_path, file_rest_path);
Console.WriteLine($"warn: {file_info.Name} ${file_type.Detected.EncodingName} 复制完成 ");
}
});
// 保持主线程运行
Console.ReadLine();