ChatGPT解决这个技术问题 Extra ChatGPT

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

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

如果您不想要 BOM,为什么要编写 GetPreamble()?

s
stakx - no longer contributing

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

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

使用 False 为 encoderShouldEmitUTF8Identifier 参数调用 UTF8Encoding 构造函数。将 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 中。
R
Roman Nikitin

尝试这个:

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

J
Joe.wang

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

请检查 File.WriteAllText 中的示例。

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


My 命名空间中的那个确实使用 BOM
T
Tao

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

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


J
JG in SD

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

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

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

如果我需要指定 leaveOpen 怎么办?
@binki 在这种情况下,您不能使用 StreamWriter 使用的默认编码。您需要为您的编码指定 new UTF8Encoding(false, true) 才能指定 leaveOpen 并且没有 BOM。
j
jos

我认为罗曼尼基丁是对的。构造函数参数的含义被翻转。 False 表示没有 BOM,true 表示有 BOM。

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


J
Jerry Banasik

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

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


F
Fred Kerber

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

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

佚名

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


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

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


在我的电脑上它会创建 ANSI 文件