5

我的理解是,读取 UTF8 或 UTF16 编码文件不一定是随机的,因为偶尔会出现代理字节(例如在东方语言中使用)。

如何使用 .NET 跳转到文件中的大致位置,并从半随机位置读取 unicode 文本?

我是否要丢弃代理字节并等待分词继续阅读?如果是这样,在开始解码之前我应该​​等待什么有效的断字?

4

3 回答 3

8

很简单,UTF-8 是自同步的。
只需跳转到文件中的随机字节并跳过读取所有带有前导位的10字节(连续字节)。没有前导的第一个字节10是正确 UFT-8 字符的起始字节,您可以使用常规 UTF-8 编码读取以下字节。

于 2011-02-08T16:55:08.277 回答
2

假设您要从 UTF-8 文件中提取伪随机字符,我个人会倾向于尝试解决如何跳入随机位置然后向前滚动到有保证的“字符开始”位置(我的感觉是一个棘手的提议)编辑 这是错误的。怎么样:

  1. 以字节为单位建立文件的长度
  2. 启发式地猜测字符的数量——例如,通过从一些合适的语料库中建立的常数进行缩放;或通过检查第一个n字节并查看它们描述了多少个字符,以获得可能更能代表此文件的缩放常数
  3. 选择一个伪随机数1..<guessed number of characters in file>
  4. 如果文件非常大(我猜它一定是,否则你不会问这个),使用缓冲读取:
  5. 读取文件的字节,解码为 UTF-8,直到达到所需的字符。如果您从文件末尾掉下来,请使用最后一个

此处的缓冲读取将需要使用两个交替“第一”的缓冲区,以避免在字符的字节被分成两次读取时丢失上下文,例如:

读取缓冲区 A:字节 1000-1999 读取缓冲区 B:字节 2000-2999

如果一个字符占用 bytes 1998-2001,使用单个缓冲区会丢失上下文。

读取缓冲区 A:字节 3000-3999

现在,当我们将字节流转换为字符时,缓冲区 A会跟随缓冲区 B。


正如下面@jleedev 所指出的,并且如另一个答案所示,“向前滚动”到有保证的字符开始实际上是简单且安全的但是上面的字符数估计东西可能仍然有用。

于 2011-02-08T16:34:13.287 回答
1

对于 UTF-16,您始终必须跳转到偶数字节位置。然后您可以检查是否有尾随代理。如果是这样,请跳过它,否则您将处于格式良好的 UTF-16 代码单元序列的开头(当然,始终假设文件格式正确)。

Unicode 编码 UTF-8 和 UTF-16 是专门为自同步而设计的,并且有强有力的保证,您最多只需要跳过少量的代码单元。

于 2011-02-09T14:32:03.997 回答