【问题标题】:Read fixed length UTF-8 strings efficiently高效读取固定长度的 UTF-8 字符串
【发布时间】:2013-05-23 19:36:01
【问题描述】:

我有一个类似数据模型的表:

fieldA (10 chracters UTF-8)

fieldB(12 characters UTF-8)

fieldC (11 characters UTF-8)

每个字段都是固定长度并写入一个文件(磁盘上的本地文件),没有任何 UTF-8 编码的分隔符(使用 StreamWriter 编写)。生成的文件如下所示:

fieldAfieldBfieldCfieldAfieldBfieldC [...]

我也知道记录的数量,可以使用 BaseStream.Seek() 随机访问文件。

假设我想读取第 29 条记录并填充我的数据模型,什么是有效(快速)的方法?我可以使用 StreamReader 并读取单个字符,但由于 UTF-8,这不是问题吗?我不想在我的数据中添加逗号并使用字符串拆分方法 - 我希望在 C# 中有更好的方法。

这不是用于生产用途,欢迎进行疯狂和微优化 :)

感谢您的帮助!

【问题讨论】:

  • 来吧,我想在我发布问题 10 秒后格式化我的帖子,@Carlos Landeras 已经这样做了?你是机器人兰德拉斯先生吗?
  • 不 :)。我是一个人:)
  • 在 UTF-8 中,一个字符被编码为 1 到 4 个字节。因此,如果您有fieldA(6 个字符)后跟fieldB,那么fieldB 可以从 1*6=6 到 4*6=24 之间的任何偏移量开始。如果不首先解码fieldA,就无法确定这一点。可能的解决方案:将每个字段填充到固定数量的字节,而不是字符。

标签: c# windows filestream


【解决方案1】:

您可以在文件中寻找合适的位置,然后使用FileStream.Read()读取合适数量的UTF8字符,然后通过以下方式将其转换为C#字符串:

string s = Encoding.UTF8.GetString(buffer, 0, buffer.Length);

或者您可以使用以正确编码打开的 StreamReader,然后使用StreamReader.Read(char[] buffer, int index, int count) 读取正确数量的字符(在寻找到正确的位置之后)。

这只有在你确实能找到正确的地方时才有效,正如你在 OP 中所说的那样!

阅读有关可变长度 UTF8 编码字符的 cmets!

【讨论】:

  • 如果文件包含 UTF-8 编码的文本,你如何“寻找文件中的适当位置”?
  • 因为 OP 说“我也知道记录的数量并且可以使用 BaseStream.Seek()”,因此我假设记录不会包含任何扩展的 UTF8 字符。我只是基于规范。 ;)
  • 感谢所有其他撰写有关 UTF-8 陷阱的人。我的代码之所以有效,是因为我目前有 1 字节的 UTF-8 字符。我必须重新考虑我的方法。
【解决方案2】:

因为 utf8 是一种可变宽度编码(即它使用可变数量的字节来表示不同的字符),所以您别无选择,只能从头开始扫描。

如果您想计算并跳转到偏移量,您需要使用固定大小的编码,即 UTF-32

【讨论】:

    【解决方案3】:

    每个字段都是固定长度的,并写入一个文件(磁盘上的本地文件),不带任何 UTF-8 编码的分隔符(使用 StreamWriter 编写)。

    您说您的字段是固定长度的。也就是说文件中的fieldA总是10字节(不管实际内容如何),fieldB总是12字节,fieldC总是11字节。

    由于上述原因,文本是 UTF-8 的事实与问题无关。

    如果你打开你的 System.IO.Stream,你可以看到你不想读取的每个字段的字节。例如,如果你想读取 fieldC,那么你可以向前搜索 22 个字节(跳过 fieldA 和 fieldB):

    stream.Seek(22, SeekOrigin.Current);
    

    一旦您在正确的位置,您就可以读取固定数量的字节,然后通过 UTF-8 将这些字节解码为您的结果字符串。

    【讨论】:

      猜你喜欢
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      相关资源
      最近更新 更多