

























你发现了一个很常见的编码问题。System.Text.Encoding.GetEncoding("utf-8") 默认情况下会使用带有BOM(Byte Order Mark,字节顺序标记)的UTF-8编码。BOM在某些场景下会导致问题,比如命令行显示乱码。
UTF-8 vs UTF-8-BOM:
EF BB BF三个字节作为标记命令行显示乱码的原因:
以下是修改后的WriteLog方法,解决编码问题:
private void WriteLog(string fileName, string msg)
{
System.IO.FileStream fst = null;
System.IO.StreamWriter swt = null;
try
{
string time = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string savePath = ConfigurationManager.AppSettings["FileTempPath"];
string filePath = Path.Combine(savePath, fileName);
// 确保目录存在
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// 使用无BOM的UTF-8编码
var utf8WithoutBom = new System.Text.UTF8Encoding(false);
// 方法1:使用StreamWriter构造函数
fst = new System.IO.FileStream(filePath, System.IO.FileMode.Append);
swt = new System.IO.StreamWriter(fst, utf8WithoutBom);
// 方法2:或者使用File.AppendText(更简洁)
// using (swt = System.IO.File.AppendText(filePath))
// {
// swt.WriteLine(time + " | " + msg.ToString());
// }
swt.WriteLine(time + " | " + msg);
}
catch (Exception ex)
{
logger.Error(ex, ex.Message);
}
finally
{
if (swt != null)
{
swt.Close();
}
if (fst != null)
{
fst.Close();
}
}
}
private void WriteLog(string fileName, string msg)
{
try
{
string time = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string savePath = ConfigurationManager.AppSettings["FileTempPath"];
string filePath = Path.Combine(savePath, fileName);
// 确保目录存在
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// 使用File.AppendText(默认无BOM的UTF-8)
using (var sw = System.IO.File.AppendText(filePath))
{
sw.WriteLine(time + " | " + msg);
}
}
catch (Exception ex)
{
logger.Error(ex, ex.Message);
}
}
private void WriteLog(string fileName, string msg, bool useUtf8Bom = false)
{
try
{
string time = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string savePath = ConfigurationManager.AppSettings["FileTempPath"];
string filePath = Path.Combine(savePath, fileName);
// 确保目录存在
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
string content = time + " | " + msg + Environment.NewLine;
// 根据参数选择编码
System.Text.Encoding encoding;
if (useUtf8Bom)
{
encoding = System.Text.Encoding.UTF8; // 带BOM
}
else
{
encoding = new System.Text.UTF8Encoding(false); // 不带BOM
}
// 追加写入文件
System.IO.File.AppendAllText(filePath, content, encoding);
}
catch (Exception ex)
{
logger.Error(ex, ex.Message);
}
}
使用new UTF8Encoding(false):
// false 表示不包含BOM
var utf8WithoutBom = new System.Text.UTF8Encoding(false);
使用File.AppendText:
使用File.AppendAllText:
改进路径处理:
Path.Combine代替字符串拼接Path.GetDirectoryName获取目录路径你可以创建一个测试方法来验证编码:
private void TestEncoding()
{
string testFile = "test_log.txt";
string testMsg = "测试中文内容";
// 写入测试日志
WriteLog(testFile, testMsg);
// 读取并检查文件编码
string filePath = Path.Combine(
ConfigurationManager.AppSettings["FileTempPath"],
testFile);
if (File.Exists(filePath))
{
byte[] bytes = File.ReadAllBytes(filePath);
if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
{
Console.WriteLine("文件包含BOM(UTF-8-BOM)");
}
else
{
Console.WriteLine("文件不包含BOM(纯UTF-8)");
}
}
}
如果需要在命令行正确显示UTF-8文件,可以:
修改命令行编码:
chcp 65001
这会将命令行编码改为UTF-8
使用支持UTF-8的终端:
在代码中显式指定编码(如果需要在命令行显示):
// 如果需要兼容命令行显示,可以使用GBK编码
var gbkEncoding = System.Text.Encoding.GetEncoding("GBK");
using (var sw = new StreamWriter(filePath, true, gbkEncoding))
{
sw.WriteLine(time + " | " + msg);
}
建议使用方案2(File.AppendText),因为它最简单且自动处理了无BOM的UTF-8编码问题。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。