有效地读取固定长度的UTF-8字符串

时间:2013-05-23 11:13:59

标签: c# windows filestream

我有一个像datamodel这样的表:

fieldA (10 chracters UTF-8)

fieldB(12 characters UTF-8)

fieldC (11 characters UTF-8)

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

fieldAfieldBfieldCfieldAfieldBfieldC [...]

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

让我们说,我想阅读第29条记录并填写我的数据模型,这将是一种有效(快速)的方法?我可以使用StreamReader并读取单个char但是因为UTF-8而没有问题吗?我不想在我的数据中添加逗号并使用字符串拆分方法 - 我希望在C#中有更好的方法。

这不适合生产用途,欢迎疯狂和微观优化:)

谢谢你的帮助!

3 个答案:

答案 0 :(得分:0)

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

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

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

这只有在您确实可以找到正确的位置时才有效,正如您在OP中所说的那样!

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

答案 1 :(得分:0)

因为utf8是一个可变宽度编码(即它使用可变数量的字节来表示不同的字符),你几乎没有选择,只能从头开始扫描。

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

答案 2 :(得分:0)

  

每个字段都是固定长度并写入文件(磁盘上的本地文件),没有任何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将这些字节解码为结果字符串。