Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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
.net System.IO.File.ReadAllText未引发无效编码异常_.net_Unicode_Utf 8_Character Encoding - Fatal编程技术网

.net System.IO.File.ReadAllText未引发无效编码异常

.net System.IO.File.ReadAllText未引发无效编码异常,.net,unicode,utf-8,character-encoding,.net,Unicode,Utf 8,Character Encoding,我在一个文件中有一些UTF-8文本utf8.txt。该文件包含一些超出ASCII范围的字符。我尝试了以下代码: var fname = "utf8.txt"; var enc = Encoding.GetEncoding("ISO-8859-1", EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback); var s = System.IO.File.ReadAllText(fname, enc); v

我在一个文件中有一些UTF-8文本
utf8.txt
。该文件包含一些超出ASCII范围的字符。我尝试了以下代码:

var fname = "utf8.txt";
var enc = Encoding.GetEncoding("ISO-8859-1", EncoderFallback.ExceptionFallback,
    DecoderFallback.ExceptionFallback);
var s = System.IO.File.ReadAllText(fname, enc);
var fname = "utf8.txt";
var utf8_bom_e_circumflex_bytes = new byte[] {0xEF, 0xBB, 0xBF, 0xC3, 0xAA};
System.IO.File.WriteAllBytes(fname, utf8_bom_e_circumflex_bytes);
预期的行为是代码应该抛出异常,因为它不是有效的ISO-8859-1文本。相反,其行为是将UTF-8文本正确解码为正确的字符(在调试器中看起来是正确的)

这是
.Net
中的错误吗

编辑:

我最初使用的文件是带有BOM的UTF-8。如果删除BOM表,行为将发生更改。它仍然不会引发异常,但会生成不正确的Unicode字符串(该字符串在调试器中看起来不正确)

编辑:

要生成测试文件,请运行以下代码:

var fname = "utf8.txt";
var enc = Encoding.GetEncoding("ISO-8859-1", EncoderFallback.ExceptionFallback,
    DecoderFallback.ExceptionFallback);
var s = System.IO.File.ReadAllText(fname, enc);
var fname = "utf8.txt";
var utf8_bom_e_circumflex_bytes = new byte[] {0xEF, 0xBB, 0xBF, 0xC3, 0xAA};
System.IO.File.WriteAllBytes(fname, utf8_bom_e_circumflex_bytes);
编辑:

我认为我对正在发生的事情有着坚定的把握(尽管我不同意.Net的部分行为)

  • 如果文件以UTF-8 BOM开头,并且数据是有效的UTF-8,则
    ReadAllText
    将完全忽略传入的编码,并(正确地)将文件解码为UTF-8。(我没有测试如果BOM是谎言,文件不是真正的UTF-8会发生什么)我不同意这种行为。我认为.Net应该抛出一个异常,或者使用我给它的编码

  • 如果文件没有BOM,.Net没有简单(100%可靠)的方法来确定文本不是真正的ISO-8859-1,因为大多数(全部?)UTF-8文本也是有效的ISO-8859-1,尽管是胡言乱语。所以它只是按照你的指令,用你给它的编码对文件进行解码。(我同意这种行为)

应引发异常,因为它不是有效的ISO-8859-1文本

在ISO-8859-1中,所有可能的字节都有到字符的映射,因此将非ISO-8859-1文件作为ISO-8859-1读取不会产生任何异常

(确实,0x80–0x9F范围内的所有字节都将成为您永远不想要的不可见控制代码,但它们仍然有效,只是没有用处。许多ISO-8859编码都是如此,它们将C1控制代码置于0x80–0x9F范围内,但不是全部。对于其他未映射字节的编码,您肯定会遇到异常,例如Windows-1252。)

如果文件以UTF-8 BOM开头,并且数据是有效的UTF-8,则ReadAllText将完全忽略传入的编码,并(正确地)将文件解码为UTF-8

是的。文件中暗示了这一点:

This method attempts to automatically detect the encoding of a file based on the presence of byte order marks.

我同意你的观点,这种行为非常愚蠢。我更喜欢
ReadAllBytes
并通过
编码.GetString
手动检查它。

你能提供一个你认为有问题的文件中的文本样本吗?我想了一下,但最好的方法是什么?我真的想发布一个二进制文件e、 也许只是一些你认为会失败的字符编码,我们可以在此基础上重新创建文本?或者我可以出去找一些模糊的utf8文本并使用它。我假设它不是一个特定的字符,只是你关心的任何无效ISO-8859-1字符都是8位编码,所以我相信字符允许从0x00到0xFF。“由于大多数(全部?)UTF-8文本也是有效的ISO-8859-1”-这仅适用于ASCII字节0x20-0x7E,它们在UTF-8和ISO-8859-1中相同。一旦超出该范围,UTF-8就不是有效的ISO-8859-1。ISO-8859-1中未定义字节0x00-0x1F和0x7F-0x9F(0x00是有争议的,因为它通常用作空终止符),而UTF-8中的大多数非ASCII字节由于UTF-8编码其位的方式而属于后一个范围。