如何移除UTF-8转ANSI编码转换后文件中的NUL字符?
UTF-8转ANSI编码后出现NUL字符的解决方法
问题场景
用户用以下C#代码将UTF-8编码文件转换为ANSI编码,转换后的文件出现大量NUL(\0)字符,但用Notepad++做相同编码转换时无此问题:
带NUL字符的文件:内容中穿插大量空白占位的NUL字符
无NUL字符的文件:内容正常显示,无无效占位符
原代码:
System.IO.FileStream fs = System.IO.File.OpenRead(@"C:\Users\Admin\Downloads\VQ\NQCUEMES221222122249.txt"); byte[] bytes = new byte[fs.Length]; fs.Read(bytes, 0, (int)fs.Length); fs.Close(); System.Text.Encoding inputEnc = System.Text.Encoding.UTF8; System.Text.Encoding outputEnc = System.Text.Encoding.Default; //System.Text.Encoding outputEnc = System.Text.Encoding.Unicode; //System.Text.Encoding outputEnc = System.Text.Encoding.ASCII; //System.Text.Encoding outputEnc = System.Text.Encoding.GetEncoding(1252); byte[] decoded = System.Text.Encoding.Convert(inputEnc, outputEnc, bytes, 0, bytes.Length); System.IO.FileStream fw = System.IO.File.OpenWrite(@"C:\Users\Admin\Downloads\VQ\NQCUEMES221222122249_NEW.txt"); fw.Write(decoded, 0, (int)decoded.Length); fw.Close(); MessageBox.Show("END");
解决方法
方法一:用字符串中转的标准编码转换流程(推荐)
直接通过StreamReader读取UTF-8内容为字符串,再用StreamWriter以ANSI编码写入,能自动处理UTF-8 BOM(字节顺序标记)和字符映射,避免NUL字符产生:
string inputPath = @"C:\Users\Admin\Downloads\VQ\NQCUEMES221222122249.txt"; string outputPath = @"C:\Users\Admin\Downloads\VQ\NQCUEMES221222122249_NEW.txt"; // 读取UTF-8文件(自动识别并跳过BOM) string content; using (var reader = new StreamReader(inputPath, Encoding.UTF8)) { content = reader.ReadToEnd(); } // 写入ANSI编码文件(Encoding.Default对应系统默认ANSI,也可指定如Encoding.GetEncoding(936)表示GB2312) using (var writer = new StreamWriter(outputPath, false, Encoding.Default)) { writer.Write(content); } MessageBox.Show("END");
方法二:手动移除UTF-8 BOM后再做字节转换
如果坚持用原代码的字节转换方式,需要先检查并移除UTF-8文件开头的BOM(EF BB BF),因为BOM字节不属于实际内容,直接转换会生成无效的NUL字符:
string inputPath = @"C:\Users\Admin\Downloads\VQ\NQCUEMES221222122249.txt"; string outputPath = @"C:\Users\Admin\Downloads\VQ\NQCUEMES221222122249_NEW.txt"; byte[] bytes = System.IO.File.ReadAllBytes(inputPath); // 检查并移除UTF-8 BOM if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { bytes = bytes.Skip(3).ToArray(); } System.Text.Encoding inputEnc = System.Text.Encoding.UTF8; System.Text.Encoding outputEnc = System.Text.Encoding.Default; byte[] decoded = System.Text.Encoding.Convert(inputEnc, outputEnc, bytes); System.IO.File.WriteAllBytes(outputPath, decoded); MessageBox.Show("END");
说明
- NUL字符的主要原因是原UTF-8文件带BOM,直接转换BOM字节会生成无效占位符;另外直接操作字节数组的方式容易忽略编码的字符边界问题。
- 用字符串中转的方式是.NET中编码转换的标准做法,能确保字符映射的正确性,同时
using语句会自动释放文件资源,比手动Close()更安全。
内容的提问来源于stack exchange,提问作者NICKBEDS
相关产品推荐
相关产品推荐

