C# StreamWriter 指定编码写入文件完整教程

C# StreamWriter 指定编码写入文件完整教程

一、带编码的构造函数重载

StreamWriter 有专门接收 Encoding 的构造器,格式:

public StreamWriter(string path, bool append, Encoding encoding);
// 进阶:自定义缓冲区大小
public StreamWriter(string path, bool append, Encoding encoding, int bufferSize);

参数说明:

  1. path:文件路径
  2. appendtrue 追加,false 覆盖原文件
  3. encoding:字符编码(UTF8、GB2312、GBK、Unicode 等)

不写编码参数时,StreamWriter 默认使用 UTF-8 带 BOM

二、常用编码示例

1. UTF-8(无BOM,推荐互联网通用)

.NET 内置 Encoding.UTF8 是带BOM的;无BOM需要手动创建:

using System;
using System.IO;
using System.Text;// UTF8 无BOM
Encoding utf8NoBom = new UTF8Encoding(false);string path = "utf8_nobom.txt";
using (StreamWriter sw = new StreamWriter(path, false, utf8NoBom))
{sw.WriteLine("测试中文 UTF8无BOM");sw.WriteLine("123abc测试");
}

2. UTF-8 默认带BOM

using (StreamWriter sw = new StreamWriter("utf8_bom.txt", false, Encoding.UTF8))
{sw.WriteLine("UTF8带BOM,记事本打开不乱码");
}

3. GB2312 / GBK(老Windows、记事本兼容)

注意:.NET Core/.NET 5+ 需要注册编码提供程序

// 程序入口先执行一次,否则GetEncoding("GB2312")报错
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);// GB2312
Encoding gbk = Encoding.GetEncoding("GB2312");using (StreamWriter sw = new StreamWriter("gb2312.txt", false, gbk))
{sw.WriteLine("中文GB2312编码");
}

4. Unicode(UTF-16 LE)

using (StreamWriter sw = new StreamWriter("unicode.txt", false, Encoding.Unicode))
{sw.WriteLine("Unicode UTF16编码");
}

三、追加写入 + 指定编码

第二个参数传 true 表示在文件末尾追加内容:

Encoding utf8NoBom = new UTF8Encoding(false);
string logPath = "log.txt";// append = true 追加
using (StreamWriter sw = new StreamWriter(logPath, true, utf8NoBom))
{sw.WriteLine($"{DateTime.Now} 追加一行日志");
}

四、配合 FileStream 底层指定编码(高级用法)

先创建文件流,再传入 StreamWriter 构造:

string path = "stream_enc.txt";
Encoding enc = Encoding.UTF8;using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs, enc))
{sw.WriteLine("通过FileStream指定编码");
}

五、异步写入并指定编码

static async Task WriteEncodeAsync()
{Encoding utf8NoBom = new UTF8Encoding(false);string path = "async_utf8.txt";using (StreamWriter sw = new StreamWriter(path, false, utf8NoBom)){await sw.WriteLineAsync("异步写入,指定UTF8无BOM");await sw.FlushAsync();}
}

六、常见问题

  1. GB2312 报错:不支持该编码
    .NET Core/.NET5+ 缺少码表提供程序,在 Program.Main 第一行添加:
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    
  2. 中文打开乱码
    • 记事本打开乱码:改用 UTF8带BOM Encoding.UTF8
    • 网页/后端读取乱码:使用 UTF8无BOM new UTF8Encoding(false)
  3. 忘记 using 导致文件锁定
    StreamWriter 实现 IDisposable,必须包裹 using,自动关闭释放流。

七、最简模板

// 覆盖写入,UTF8无BOM
var enc = new UTF8Encoding(false);
using var sw = new StreamWriter("test.txt", false, enc);
sw.WriteLine("内容");
// 追加写入,GB2312
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding("GB2312");
using var sw = new StreamWriter("log.txt", true, enc);
sw.WriteLine("追加日志");