【问题标题】:Write text files without Byte Order Mark (BOM)?编写没有字节顺序标记 (BOM) 的文本文件?
【发布时间】:2011-01-27 02:48:24
【问题描述】:

我正在尝试使用带有 UTF8 编码的 VB.Net 创建一个没有 BOM 的文本文件。任何人都可以帮助我,如何做到这一点?
我可以使用 UTF8 编码编写文件,但是,如何从中删除字节顺序标记?

编辑1: 我试过这样的代码;

    Dim utf8 As New UTF8Encoding()
    Dim utf8EmitBOM As New UTF8Encoding(True)
    Dim strW As New StreamWriter("c:\temp\bom\1.html", True, utf8EmitBOM)
    strW.Write(utf8EmitBOM.GetPreamble())
    strW.WriteLine("hi there")
    strW.Close()

        Dim strw2 As New StreamWriter("c:\temp\bom\2.html", True, utf8)
        strw2.Write(utf8.GetPreamble())
        strw2.WriteLine("hi there")
        strw2.Close()

1.html 仅使用 UTF8 编码创建,2.html 使用 ANSI 编码格式创建。

简化方法 - http://whatilearnttuday.blogspot.com/2011/10/write-text-files-without-byte-order.html

【问题讨论】:

  • 如果你不想要BOM,你为什么要写GetPreamble()?

标签: vb.net encoding file-handling byte-order-mark


【解决方案1】:

为了省略字节顺序标记 (BOM),您的流必须使用 UTF8Encoding 的实例,而不是 System.Text.Encoding.UTF8(配置为生成 BOM)。有两种简单的方法可以做到这一点:

1.明确指定合适的编码:

  1. 使用False 调用UTF8Encoding constructor 以获得encoderShouldEmitUTF8Identifier 参数。

  2. UTF8Encoding 实例传递给流构造函数。

' VB.NET:
Dim utf8WithoutBom As New System.Text.UTF8Encoding(False)
Using sink As New StreamWriter("Foobar.txt", False, utf8WithoutBom)
    sink.WriteLine("...")
End Using
// C#:
var utf8WithoutBom = new System.Text.UTF8Encoding(false);
using (var sink = new StreamWriter("Foobar.txt", false, utf8WithoutBom))
{
    sink.WriteLine("...");
}

2。使用默认编码:

如果您根本不向StreamWriter 的构造函数提供Encoding,则StreamWriter 将默认使用不带BOM 的UTF8 编码,因此以下内容应该同样有效:

' VB.NET:
Using sink As New StreamWriter("Foobar.txt")
    sink.WriteLine("...")
End Using
// C#:
using (var sink = new StreamWriter("Foobar.txt"))
{
    sink.WriteLine("...");
}

最后,请注意省略 BOM 仅适用于 UTF-8,不适用于 UTF-16。

【讨论】:

  • 并不总是明智的:例如My.Computer.FileSystem.WriteAllText 如果未指定编码,则写入 BOM。
  • My.Computer.FileSystem.WriteAllText 在这方面是个例外,也许是为了向后兼容 VB? File.WriteAllText 默认为 UFT8NoBOM。
  • 如果您想为 VLC 编写 *.m3u8 播放列表文件,这将特别有用。 VLC 仍然无法使用 BOM 读取 UTF8 播放列表文件!这似乎是根据trac.videolan.org/vlc/ticket/21860 修复的,但只会包含在 VLC v4 中。
【解决方案2】:

试试这个:

Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM
TextWriter file = new StreamWriter(filePath, false, outputEnc); // open file with encoding
// write data here
file.Close(); // save and close it

【讨论】:

    【解决方案3】:

    只需使用System.IO.File中的WriteAllText方法即可。

    请查看File.WriteAllText的样本。

    此方法使用不带字节顺序标记 (BOM) 的 UTF-8 编码,因此 使用 GetPreamble 方法将返回一个空字节数组。如果是 必须包含 UTF-8 标识符,例如字节顺序标记,在 文件的开头,使用 WriteAllText(String, String, Encoding) 方法重载,使用 UTF8 编码。

    【讨论】:

    • My 命名空间中的那个确实使用了 BOM
    【解决方案4】:

    对此的有趣说明:奇怪的是,System.IO.File 类的静态“CreateText()”方法创建 UTF-8 文件没有 BOM。

    通常这是错误的来源,但在您的情况下,它可能是最简单的解决方法:)

    【讨论】:

      【解决方案5】:

      如果您在创建新的StreamWriter 时未指定Encoding,则使用的默认Encoding 对象是UTF-8 No BOM,它是通过new UTF8Encoding(false, true) 创建的。

      所以要创建一个不使用 BOM 的文本文件,使用不需要您提供编码的构造函数:

      new StreamWriter(Stream)
      new StreamWriter(String)
      new StreamWriter(String, Boolean)
      

      【讨论】:

      • 如果我需要指定leaveOpen怎么办?
      • @binki 在这种情况下,您不能使用StreamWriter 使用的默认编码。您需要为您的编码指定 new UTF8Encoding(false, true) 才能指定 leaveOpen 而没有 BOM。
      【解决方案6】:

      我认为 Roman Nikitin 是对的。构造函数参数的含义被翻转。 False 表示没有 BOM,true 表示有 BOM。

      您会获得 ANSI 编码,因为没有 BOM 且不包含非 ansi 字符的文件与 ANSI 文件完全相同。在“hi there”字符串中尝试一些特殊字符,您会看到 ANSI 编码更改为 without-BOM。

      【讨论】:

        【解决方案7】:

        没有 BOM 的 XML 编码 UTF-8
        我们需要将 XML 数据提交给 EPA,他们接受我们输入的应用程序需要没有 BOM 的 UTF-8。哦,是的,普通的 UTF-8 应该是每个人都可以接受的,但不是 EPA 可以接受的。这样做的答案在上面的 cmets 中。谢谢罗马尼基丁

        这里是 XML 编码的 C# sn-p 代码:

            Encoding utf8noBOM = new UTF8Encoding(false);  
            XmlWriterSettings settings = new XmlWriterSettings();  
            settings.Encoding = utf8noBOM;  
                …  
            using (XmlWriter xw = XmlWriter.Create(filePath, settings))  
            {  
                xDoc.WriteTo(xw);  
                xw.Flush();  
            }    
        

        查看这是否真的从输出文件中删除了三个前导字符可能会产生误导。例如,如果您使用 Notepad++ (www.notepad-plus-plus.org),它将报告“Encode in ANSI”。我猜大多数文本编辑器都依靠 BOM 字符来判断它是否是 UTF-8。清楚地看到这一点的方法是使用像 WinHex (www.winhex.com) 这样的二进制工具。因为我正在寻找前后差异,所以我使用了 Microsoft WinDiff 应用程序。

        【讨论】:

          【解决方案8】:

          对于 VB.Net Visual Basic,这是如何使其工作的:

          My.Computer.FileSystem.WriteAllText("FileName", Data, False, System.Text.Encoding.ASCII)
          

          【讨论】:

            【解决方案9】:

            您的输入文本可能包含字节顺序标记。在这种情况下,您应该在写入之前将其删除。

            【讨论】:

            • 请帮助我。如何在写入之前将其删除。
            • @user180326 默认阅读器不是已经为您过滤掉了吗?
            【解决方案10】:
            Dim sWriter As IO.StreamWriter = New IO.StreamWriter(shareworklist & "\" & getfilename() & ".txt", False, Encoding.Default)
            

            给你想要的结果(我认为)。

            【讨论】:

            • 在我的电脑上它会创建 ANSI 文件
            猜你喜欢
            • 2011-12-31
            • 2013-06-23
            • 2011-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-28
            • 2011-04-21
            • 1970-01-01
            相关资源
            最近更新 更多