【问题标题】:How to output Byte Order Mark when writing to TextWriter?写入TextWriter时如何输出字节顺序标记?
【发布时间】:2012-08-31 18:30:04
【问题描述】:

我正在向TextWriter 写信。我希望 UTF-16 字节顺序标记 (BOM) 出现在输出中:

public void ProcessRequest(HttpContext context)
{
   context.Response.ContentEncoding = new UnicodeEncoding(true, true);
   WriteStuffToTextWriter(context.Response.Output);
}

除了输出不包含字节顺序标记:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Thu, 06 Sep 2012 21:09:23 GMT
X-AspNet-Version: 4.0.30319
Content-Disposition: attachment; filename="Transactions_Calendar_20120906.csv"
Cache-Control: private
Content-Type: text/csv; filename="Transactions_Calendar_20120906.csv"; charset=utf-16BE
Content-Length: 95022
Connection: Close

JobName,ShiftName,6////09////2012 12::::00::::00 АΜ,...

我如何告诉TextWriter 编写编码标记?

注意2nd paramter in UnicodeEncoding

   context.Response.ContentEncoding = new UnicodeEncoding(true, true);

byteOrderMark
键入:System.Boolean
true 以指定提供 Unicode 字节顺序标记;否则,false

【问题讨论】:

  • WriteStuffToTextWriter 到底是什么,您可能必须在 StreamWriter 中指定编码
  • 是什么让您说它不包含您拥有的代码的 BOM?
  • 我和@JonHanna 在一起。另外,您是否尝试过创建控制台应用程序并将相同的内容直接写入文件并查看它的外观?毕竟,在您的网络服务器和浏览器之间发生了很多事情
  • 控制台应用程序也应该隐藏 BOM,BOM 的全部意义在于它不会作为文本的一部分出现,而是提供有关谁将其从八位字节解码为文本的数据。上面流的十六进制视图会显示 FE 和 FF 或 FF 和 FE(这些字节的顺序正是字节顺序标记要显示的内容,因为 U+FFFE 不是有效字符,所以只有一个命令可能是正确的)。 Fiddler 有一个十六进制视图。

标签: c# encoding utf-8 utf-16 textwriter


【解决方案1】:

短版

String zwnbsp = "\xfeff"; //Zero-width non-breaking space

//The Zero-width non-breaking space character ***is*** the Byte-Order-Mark (BOM).
String s = zwnbsp+"The quick brown fox jumped over the lazy dog.";
writer.Write(s);

加长版

在某个时候,我意识到解决方案是多么简单。

曾经认为 Unicode Byte-Order-Mark 是一些特殊的签名。我曾经认为我必须仔细决定要输出哪个字节序列,才能输出正确的 BOM:

  • 0xFE 0xFF
  • 0xFF 0xFE
  • 0xEF 0xBB 0xBF

但从那时起,我意识到字节 Byte-Order-Mark 不是一些特殊的字节序列,您必须将其添加到文件中。

BOM 只是一个Unicode 字符。您不输出任何字节;你只输出字符U+FEFF。在编写该字符的行为中,序列化程序会将其转换为您正在使用的任何编码您。

选择角色U+feff (ZERO WIDTH NO-BREAK SPACE) 是有充分理由的。它是一个空格,所以没有任何意义,而且它是零宽度,所以你根本不应该看到它。

这意味着我的问题存在根本缺陷。没有像“写一个字节顺序标记”这样的东西。您只需确保您写出的第一个字符是U+FEFF。就我而言,我正在写信给TextWriter

void WriteStuffToTextWriter(TextWriter writer)
{
   String csvExport = GetExportAsCSV();

   writer.Write("\xfeff"); //Output unicode charcter U+FEFF as a byte order marker
   writer.Write(csvExport);
}

TextWriter 将处理将 unicode 字符 U+feff 转换为它已配置使用的任何字节编码。

注意:任何代码都会发布到公共领域。无需署名。

【讨论】:

    【解决方案2】:

    写出 context.Response.ContentEncoding.GetPreamble()。看看Write text files without Byte Order Mark (BOM)?

    【讨论】:

    • 不过要小心。我不确定他们实际上是否已经在输出 BOM。第二个 U+FEFF 将被解释为实际文本开头的零宽度不间断空格,在 BOM 之后。
    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多