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


116

我正在尝试使用带有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


8
如果您不需要BOM,为什么要编写GetPreamble()?
汉斯·帕桑特2010年

Answers:


200

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

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

  1. 调用UTF8Encoding构造函数FalseencoderShouldEmitUTF8Identifier参数。

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

如果您根本不提供Encodingto StreamWriter的构造函数,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("...");
}

最后,请注意,仅对于UTF-8允许省略BOM,对于UTF-16不允许。


并非总是明智的:例如My.Computer.FileSystem.WriteAllText,如果未指定编码,则写入BOM。
beppe9000 '16

My.Computer.FileSystem.WriteAllText在这方面是个例外,也许是为了向后兼容VB?File.WriteAllText默认为UFT8NoBOM。
jnm2

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

6

只需简单地使用的方法WriteAllTextSystem.IO.File

请检查File.WriteAllText中的示例。

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


My名称空间中的一个确实使用BOM
beppe9000,2016年

4

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

通常,这是错误的来源,但就您而言,这可能是最简单的解决方法:)


4

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

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

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

如果需要指定leaveOpen怎么办?
2015年

在这种情况下,@ binki无法使用所使用的默认编码StreamWriter。您需要指定new UTF8Encoding(false, true)编码,以便能够指定但leaveOpen没有BOM。
SD

3

我认为Roman Nikitin是对的。构造函数参数的含义被翻转。False表示没有物料清单,True表示具有物料清单。

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


1

不带BOM的XML编码UTF-8
我们需要将XML数据提交给EPA,并且接受我们输入的应用程序需要不带BOM的UTF-8。哦,是的,普通的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应用程序。


-1

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


1
请帮我 写之前如何删除它。
维杰·巴尔卡瓦德

@ user180326还不是默认的阅读器已经为您过滤掉了吗?
宾基2015年

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

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


1
在我的PC上,它会创建ANSI文件
Muflix
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.