编写没有字节顺序标记(BOM)的文本文件?

时间:2010-03-13 07:43:26

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

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

EDIT1: 我试过像这样的代码;

    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

9 个答案:

答案 0 :(得分:194)

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

<强> 1。明确指定合适的编码:

  1. 使用FalseencoderShouldEmitUTF8Identifier参数调用UTF8Encoding constructor

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

  3. ' 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。使用默认编码:

    如果您根本没有提供EncodingStreamWriter的构造函数,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。

答案 1 :(得分:28)

试试这个:

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

答案 2 :(得分:6)

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

请查看File.WriteAllText中的示例。

  

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

答案 3 :(得分:4)

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

一般来说这是bug的来源,但在你的情况下,它可能是最简单的解决方法:)

答案 4 :(得分:4)

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

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

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

答案 5 :(得分:3)

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

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

答案 6 :(得分:1)

XML编码UTF-8无BOM
我们需要向EPA提交XML数据,他们的应用程序需要输入UTF-8而不需要BOM。哦,是的,普通的UTF-8应该适合所有人,但不适用于EPA。这样做的答案在上面的评论中。谢谢 Roman Nikitin

以下是XML编码代码的C#代码段:

    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),它将报告“ANSI编码”。我想大多数文本编辑都指望BOM字符来判断它是否是UTF-8。清楚地看到这一点的方法是使用像 WinHex 这样的二进制工具(www.winhex.com)。由于我在寻找前后差异,因此我使用了Microsoft WinDiff 应用程序。

答案 7 :(得分:-1)

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

答案 8 :(得分:-1)

Dim sWriter As IO.StreamWriter = New IO.StreamWriter(shareworklist & "\" & getfilename() & ".txt", False, Encoding.Default)

为您提供您想要的结果(我认为)。