如何完成UTF8文件的随机读取

时间:2011-02-08 15:35:31

标签: c# unicode utf-8 utf-16 utf8-decode

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

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

我是否丢弃代理字节并等待分词继续阅读?如果是这样,在我开始解码之前,我应该等待valid word breaks是什么?

3 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:2)

假设您正在寻找从UTF-8文件中提取伪随机字符,我个人会倾向于试图找出如何跳转到随机位置然后向前滚动到保证的'字符开头'位置(我感觉这将是一个棘手的主张)编辑 这是错误的。怎么样:

  1. 以字节为单位确定文件的长度
  2. 启发式地猜测字符的数量 - 例如,通过从某个合适的语料库建立的常数进行缩放;或者通过检查第一个n字节并查看它们描述了多少个字符,以获得可能更能代表此文件的缩放常量
  3. 1..<guessed number of characters in file>
  4. 中选择一个伪随机数
  5. 如果文件非常大(我猜它必须是,否则你不会问这个),请使用缓冲读取:
  6. 读取文件的字节,解码为UTF-8,直到找到所需的字符。如果您从文件末尾删除,请使用最后一个
  7. 这里的缓冲读取将需要使用两个缓冲区,这两个缓冲区交替“第一个”以避免在字符的字节被分成两个读取时丢失上下文,例如:

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

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

    读缓冲区A:字节3000-3999

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


    如下面@jleedev所述,并且正如在另一个答案中所看到的, 实际上很容易安全地“向前滚动”到有保证的字符开头。但上面的字符数估计可能仍然有用。

答案 2 :(得分:1)

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

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