Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用StreamReader读取编码标识符_C# - Fatal编程技术网

C# 使用StreamReader读取编码标识符

C# 使用StreamReader读取编码标识符,c#,C#,我正在读一本C#书,在关于流的一章中说: 如果显式指定编码,默认情况下StreamWriter将, 在流的开头写入前缀以标识编码。 这通常是不可取的,您可以通过构造 编码如下: var encoding=新的UTF8编码(编码器应提交UTF8identifier:false,throwOnInvalidBytes:true) 我想实际查看标识符的外观,因此我提出了以下代码: using (FileStream fs = File.Create ("test.tx

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

如果显式指定编码,默认情况下StreamWriter将, 在流的开头写入前缀以标识编码。 这通常是不可取的,您可以通过构造 编码如下:

var encoding=新的UTF8编码(编码器应提交UTF8identifier: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表的原始代码的变体:

使用(MemoryStream stream=new MemoryStream())
{
编码编码=新的UTF8Encoding(编码器应提交UTF8Identifier:true);
使用(TextWriter writer=newstreamwriter(流,编码,缓冲区大小:8192,leaveOpen:true))
{
writer.WriteLine(“第1行”);
}
流位置=0;
编码=新的UTF8Encoding(编码器应提交UTF8Identifier:false);
使用(TextReader reader=new StreamReader(流、编码、detectEncodingFromByteOrderMarks:false))
{
对于(intb;(b=reader.Read())>-1;)
Console.WriteLine(b++(char)b);//未打印标识符
}
}
此处,
encoderShouldEmitUTF8Identifier:true
传递给用于创建流的编码器,以便在创建流时写入BOM,但
encoderShouldEmitUTF8Identifier:false
传递给用于读取流的编码器,这样,当流被读回时,BOM表将被视为普通字符。
detectEncodingFromByteOrderMarks:false
参数也会传递给
StreamReader
构造函数,这样它就不会使用BOM表本身

这将生成此输出,正如您所希望的:

65279 ? 76 L 105 i 110 n 101 e 49 1 13 10 65279 ? 76升 105 i 110 n 101 e 49 1 13 10
值得一提的是,通常不鼓励使用BOM作为标识UTF8编码的一种形式。BOM的存在主要是为了区分UTF16的两种变体(即UTF16LE和UTF16BE,分别为“小端”和“大端”)。它也被用作识别UTF8的一种方法,但实际上最好只知道编码是什么(这就是为什么XML和HTML等东西在文件的第一部分明确地将编码声明为ASCII,并且MIME的
字符集
属性存在的原因)。单个字符远不如其他更明确的方法可靠。

StreamReader检测BOM并将其删除。您必须使用FileStream.Read()才能查看它。您还可以签出编码器实例的,以获取使用的字节。您可以在此处查看前缀值: