.NET流解码器行为

.NET流解码器行为,.net,unicode,stream,binary-data,decoding,.net,Unicode,Stream,Binary Data,Decoding,我有一个过程,它试图从二进制流中解码字符串的不同编码。当我一步一步走过的时候,我的一些行为并没有在我的脑海中积累起来。具体而言,我所做的是: 获取用于在给定编码中对字符进行编码的最大字节数 从流中获取字节数 使用Encoding.GetCharCount确定这些字节中可能编码的字符数可能是0或1或2。。。 如果不是零,我将使用Encoding.GetString从字节数组中提取字符 然后,我计算出用于对提取的字符进行编码的字节数,并将流索引提升该数量 如果可解码字节数为零,我将索引提前一个字节,

我有一个过程,它试图从二进制流中解码字符串的不同编码。当我一步一步走过的时候,我的一些行为并没有在我的脑海中积累起来。具体而言,我所做的是:

获取用于在给定编码中对字符进行编码的最大字节数 从流中获取字节数 使用Encoding.GetCharCount确定这些字节中可能编码的字符数可能是0或1或2。。。 如果不是零,我将使用Encoding.GetString从字节数组中提取字符 然后,我计算出用于对提取的字符进行编码的字节数,并将流索引提升该数量 如果可解码字节数为零,我将索引提前一个字节,然后再次尝试整个操作……以这种方式,我希望不会遗漏任何可解码字符 顺便说一句,如果有人注意到上面所做的任何不正确的假设,请随意说

我将解码器设置为在无法解码给定字节集时抛出DedCoderFallbackException。让我困惑的是,有时调用GetCharCount时会出现异常,有时调用GetString时会出现异常。这有什么原因吗?这真的是意料之中的吗?我希望能够在尽可能少的地方可靠地检查是否存在可打印字符-目前我正在多个地方进行检查

有什么想法吗

谢谢, 布莱恩

重大更新: 我对这个问题的最初描述似乎有点欠缺。让我为这个问题补充几个前提:

该流可能非常大-对于大多数用户来说,它不适合存储在内存中 在流中的任何地方,我都不知道我在文本的开头,在文本的中间。 在流中的任何给定的地方,我不知道我是在中间还是从多字节字符开始。 流将包含许多事实上不是任何类型的文本的材料,以及少量不同的编码
希望这能澄清一些问题。到目前为止,回复非常有用!请继续

像UTF8这样的编码对字符使用可变的字节数,因此不能简单地将从流中提取的最大字节数相乘。最后一个字节可能位于字符的中间,并且可能单独无效,或者最后一个字符可能代表该特定编码中完全不同的字符。

像UTF8这样的编码使用可变的字符字节数,因此不能简单地乘以从流中提取的最大字节数。最后一个字节可能位于字符的中间,并且可能单独无效,或者最后一个字符可能代表该特定编码中完全不同的字符。

Wow。听起来好像太过分了。您是否尝试过使用编码的GetDecoder方法?它提供给您一个带有GetChars方法的解码器,您可以将字节数组和字符数组提供给该解码器,并使用从字节数组解码的可用字符填充字符数组

如果存在任何超调,即空闲字节,则这些字节将保存在解码器的状态中,以备下次使用新字节调用GetChars时使用

可以使用StringBuilder组装结果


比你的方法简单一点。

哇。听起来好像太过分了。您是否尝试过使用编码的GetDecoder方法?它提供给您一个带有GetChars方法的解码器,您可以将字节数组和字符数组提供给该解码器,并使用从字节数组解码的可用字符填充字符数组

如果存在任何超调,即空闲字节,则这些字节将保存在解码器的状态中,以备下次使用新字节调用GetChars时使用

可以使用StringBuilder组装结果


比您的方法简单一点。

如果我正确理解您的问题,您是否试图从未知编码的字节流中读取字符数据

如果我的假设是正确的,那么您首先需要检测编码,并使用此编码读取字节流,然后您将不需要担心不同的字符大小,TextReader将为您完成所有工作

我知道从字节流检测编码的两种方法:

.
若我正确理解了你们的问题,你们试图从未知编码的字节流中读取字符数据吗

如果我的假设是正确的,那么您首先需要检测编码,并使用此编码读取字节流,然后您将不需要担心不同的字符大小,TextReader将为您完成所有工作

我知道从字节流检测编码的两种方法:

.
很好的一点-我想我已经解释了这个问题,虽然我在我的原始帖子中没有提到任何问题…我会详细说明。嗯,现在我想起来了,我可能会错误地解码看起来像文本的材料,但是

事实上,这只是巧合,我会在一个不正确的偏移点上,对吗?有什么办法吗?可能吧。这可能会发生,具体取决于编码。为了安全地执行此操作,您应该在它们前面加上字节数和编码。如果字节在另一种编码中看起来也像有效文本,而您首先尝试了这种编码,那该怎么办?首先,我不是执行初始编码的那个人,所以我必须假设数据在到达它时或多或少是完整的。第二,我可以在相同的字节块上尝试不同的编码,但接下来我该怎么做——看看哪一个解码的字符最多?确实,总有出错的空间。例如,Web浏览器使用启发式方法来检测编码,但就我个人而言,我曾多次面临错误的编码检测,并在网页上显示垃圾,因此不得不手动设置该网页的编码。事实上,编码就像一个契约。你应该在沟通之前就已经同意了。否则,这将归结为猜测,这一点都不容易,你应该使用一个库来进行猜测,但是会有错误的空间。很好的一点-我认为我已经解释了这个问题,尽管我在我的原始帖子中没有提到任何这一点…我会详细说明。嗯,现在我想起来了,似乎我可能会错误地解码看起来像文本的材料,但实际上只是巧合,在这一点上,我会在一个不正确的偏移量上,对吗?有什么办法吗?可能吧。这可能会发生,具体取决于编码。为了安全地执行此操作,您应该在它们前面加上字节数和编码。如果字节在另一种编码中看起来也像有效文本,而您首先尝试了这种编码,那该怎么办?首先,我不是执行初始编码的那个人,所以我必须假设数据在到达它时或多或少是完整的。第二,我可以在相同的字节块上尝试不同的编码,但接下来我该怎么做——看看哪一个解码的字符最多?确实,总有出错的空间。例如,Web浏览器使用启发式方法来检测编码,但就我个人而言,我曾多次面临错误的编码检测,并在网页上显示垃圾,因此不得不手动设置该网页的编码。事实上,编码就像一个契约。你应该在沟通之前就已经同意了。否则,这将归结为猜测,这一点都不容易,你应该使用一个库来实现这一点,但会有出错的空间。我真的不明白你为什么要这么做。如果可能的话,最有效的方法就是把整个过程读入内存,然后一次处理完。我真的不明白你为什么要这么做。如果可能的话,最有效的方法是将整个过程读入内存,然后一次处理完。不幸的是,我不这么认为。我不知道文本的开头,也不知道任何给定位置的实际编码。我想这会阻止我使用GetEncoding,对吗?不幸的是,我不这么认为。我不知道文本的开头,也不知道任何给定位置的实际编码。我想这会阻止我使用GetEncoding,对吗?你的假设确实是正确的。一有机会我就去看看你贴的图书馆。可能需要几天,但如果它有效,我会检查并更新线程。实际上我自己没有使用Ude,因为我在一个月前才找到它。但是MultiLang对我来说非常有效。但是我建议首先尝试Ude,因为这是一个完全管理的解决方案。只需使用网站上提供的示例代码和一个非常简单的.txt文件作为输入流就可以尝试Ude。它无法理解编码。我还尝试了一个docx文件,但同样没有结果……它似乎只适用于网站,即打开一个网站,下载页面,将其作为文件流打开,并将其用作输入。虽然这很酷,但仍然不能解决问题。当然值得一看。你的假设确实是正确的。一有机会我就去看看你贴的图书馆。可能需要几天,但如果它有效,我会检查并更新线程。实际上我自己没有使用Ude,因为我在一个月前才找到它。但是MultiLang对我来说非常有效。但是我建议首先尝试Ude,因为这是一个完全管理的解决方案。只需使用网站上提供的示例代码和一个非常简单的.txt文件作为输入流就可以尝试Ude。它无法理解编码。我还尝试了一个docx文件,但同样没有结果……它似乎只适用于网站,即打开一个网站,下载页面,将其作为文件流打开,并将其用作输入。虽然这很酷,但仍然不能解决问题。不过绝对值得一看。