有效地读取固定长度的UTF-8字符串
本文关键字:UTF-8 字符串 读取 有效地 | 更新日期: 2023-09-27 18:15:12
我有一个类似数据模型的表:
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#中有更好的方法。
这不是用于生产使用,欢迎疯狂和微优化:)
谢谢你的帮助!
您可以查找到文件中的适当位置,然后使用FileStream.Read()
读取适当数量的UTF8字符,然后通过以下方式将其转换为c#字符串:
string s = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
或者您可以使用以正确编码打开的StreamReader,然后使用StreamReader.Read(char[] buffer, int index, int count)
读取正确数量的字符(在寻找正确的位置之后)。
这只会工作,如果你确实可以寻求正确的地方,正如你在OP中所说的!
阅读关于变长utf8编码字符的注释!
由于utf8是可变宽度编码(即使用可变字节数来表示不同的字符),您几乎没有选择,只能从头开始扫描。
如果你想计算并跳转到偏移量,你需要使用固定大小的编码,即UTF-32
每个字段都是固定长度并写入一个文件(磁盘上的本地文件),不使用任何分隔符以UTF-8编码(使用StreamWriter写入)。
你说你的字段是固定长度的。这意味着文件中的fieldA始终是10字节(不管实际内容如何),fieldB始终是12字节,fieldC始终是11字节。
由于上述原因,文本是UTF-8与问题无关。
如果你打开System.IO。流中,您可以看到不想读取的每个字段的字节。例如,如果您想读取fieldC,那么您可以提前查找22字节(跳过fieldA和fieldB):
stream.Seek(22, SeekOrigin.Current);
一旦你在正确的位置,你可以读取固定数量的字节,然后通过UTF-8解码这些字节到你的结果字符串。