【问题标题】:C# StreamWriter writes extra bytes to the StreamC# StreamWriter 将额外的字节写入 Stream
【发布时间】:2020-06-03 12:10:07
【问题描述】:
var memStream = new MemoryStream();
using (var sw = new StreamWriter(memStream, Encoding.UTF8, 4194304 /* 4 MiB */, leaveOpen: true))
{
     var str = new string(Enumerable.Repeat(' ', 10240 /* 10 * KiB */).ToArray());
     Console.WriteLine(str.Length);
     Console.WriteLine(Encoding.UTF8.GetBytes(str).Length);
     sw.Write(str);
     sw.Flush();
     Console.WriteLine(memStream.Length);
}
// Output
// ---------
// 10240
// 10240
// 10243

// Output which I was expecting
// ---------
// 10240
// 10240
// 10240

我检查了 MSDN 上的 StreamWriter.Write(String) 文档,但没有找到任何提到此 API 可以将额外字节写入流的内容。 (MSDN Doc StreamWriter.Write)。 我正在使用 .NET Core 3.1,但我猜这种行为也适用于 Core 2.0 和 Framework,尽管我没有明确地测试我的假设。我彻底阅读了StreamWriter 文档,我没有发现任何关于这种行为的提及。这是错误还是预期行为,还是我遗漏了什么?

【问题讨论】:

  • 虽然你已经包含了你得到的结果,但你没有包含你期望看到的结果。请补充。
  • 我将 10243 视为输出的最后一行 - 这是我对一开始添加 BOM 的期望。您是否反复得到 10305?
  • 我也只看到 10243 作为最终尺寸。
  • 这里也一样;但是:如果您不想要 BOM,请使用 new UTF8Encoding(false)

标签: c# .net .net-core


【解决方案1】:

当我在本地运行时,我得到了

10240
10240
10243

进一步检查,额外的 3 个字节似乎位于流 239 187 191EF BB BF 的十六进制开头。这是字节顺序标记 (BOM) https://en.wikipedia.org/wiki/Byte_order_mark

要从输出中删除这些额外字符,请使用 new UTF8Encoding(false) 省略 BOM,而不是在创建 StreamWriter 时使用 Encoding.UTF8

using (var sw = new StreamWriter(memStream, new UTF8Encoding(false), 4194304 /* 4 MiB */, leaveOpen: true))

【讨论】:

  • 谢谢 :) 。我不知道 StreamWriter 默认会添加 BOM。
  • @amit9oct 见remarks
【解决方案2】:

您可以通过使用 new UTF8Encoding(false) 创建不应发出 UTF8 标识符的 UTF8Encoding 来阻止 BOM 的输出:

var memStream = new MemoryStream();
using (var sw = new StreamWriter(memStream, new UTF8Encoding(false), 4194304 /* 4 MiB */, leaveOpen: true))
{
    var str = new string(Enumerable.Repeat(' ', 10240 /* 10 * KiB */).ToArray());
    Console.WriteLine(str.Length);
    Console.WriteLine(Encoding.UTF8.GetBytes(str).Length);
    sw.Write(str);
    sw.Flush();
    Console.WriteLine(memStream.Length);
}

【讨论】:

  • 谢谢 :) 。我不知道 StreamWriter 默认会添加 BOM。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-23
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 2014-04-18
  • 1970-01-01
相关资源
最近更新 更多