gpt4 book ai didi

c# - 使用 StreamReader 读取编码标识符

转载 作者:太空宇宙 更新时间:2023-11-03 14:38:36 25 4
gpt4 key购买 nike

我正在读一本 C# 书,在关于流的章节中它说:

If you explicitly specify an encoding, StreamWriter will, by default,write a prefix to the start of the stream to identify the encoding.This is usually undesirable and you can prevent it by constructing theencoding as follows:

var encoding = new UTF8Encoding (encoderShouldEmitUTF8Identifier:false, throwOnInvalidBytes:true);

我想看看标识符的实际情况,所以我想出了这段代码:

            using (FileStream fs = File.Create ("test.txt"))
using (TextWriter writer = new StreamWriter (fs,new UTF8Encoding(true,false)))
{
writer.WriteLine ("Line1");
}

using (FileStream fs = File.OpenRead ("test.txt"))
using (TextReader reader = new StreamReader (fs))
{
for (int b; (b = reader.Read()) > -1;)
Console.WriteLine (b + " " + (char)b); // identifier not printed
}

令我不满意的是,没有打印标识符。如何读取标识符?我错过了什么吗?

最佳答案

默认情况下,.NET 会非常努力地避免编码错误。如果你想看到字节顺序标记,也就是“序言”或“BOM”,你需要非常明确地使用对象来禁用自动行为。这意味着您需要使用不包含前导码的编码,并且您需要告诉 StreamReader 不要尝试检测编码。

这是将显示 BOM 的原始代码的变体:

using (MemoryStream stream = new MemoryStream())
{
Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);

using (TextWriter writer = new StreamWriter(stream, encoding, bufferSize: 8192, leaveOpen: true))
{
writer.WriteLine("Line1");
}

stream.Position = 0;
encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

using (TextReader reader = new StreamReader(stream, encoding, detectEncodingFromByteOrderMarks: false))
{
for (int b; (b = reader.Read()) > -1;)
Console.WriteLine(b + " " + (char)b); // identifier not printed
}
}

这里,encoderShouldEmitUTF8Identifier: true 被传递给用于创建流的编码器,以便在创建流时写入 BOM,但是 encoderShouldEmitUTF8Identifier: false 是传递给用于读取流的编码器,以便在回读流时将 BOM 视为普通字符。 detectEncodingFromByteOrderMarks: false 参数也传递给 StreamReader 构造函数,因此它不会消耗 BOM 本身。

这会产生这个输出,就像你想要的那样:

65279 ?76 L105 i110 n101 e49 11310

值得一提的是,通常不鼓励使用 BOM 作为识别 UTF8 编码的形式。 BOM 的存在主要是为了区分 UTF16 的两种变体(即 UTF16LE 和 UTF16BE,分别为“小端”和“大端”)。它也被用作识别 UTF8 的一种方式,但实际上最好只知道编码是什么(这就是为什么像 XML 和 HTML 之类的东西在文件的第一部分明确地将编码声明为 ASCII,而 MIME 的charset 属性存在)。单个字符远不如其他更明确的方式可靠。

关于c# - 使用 StreamReader 读取编码标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58896085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com