用自定义定界符和C#中一些非常大的字段值解析文本的最快方法是什么?

我一直在尝试处理一些带有非标准定界符(不是逗号/引号或制表符定界)的定界文本文件.分隔符是随机的ASCII字符,通常不会在分隔符之间出现.经过四处搜寻,我似乎只发现.NET中没有解决方案可以满足我的需求,而人们为此编写的自定义库似乎在巨大输入方面存在一些缺陷(4GB文件具有一些字段值,非常容易地获得数百万个字符).

尽管这似乎有些极端,但实际上,对于某些审阅软件来说,具有包含文档完整内容的字段值是电子文档发现(EDD)行业的标准.作为参考,我之前已经使用csv模块在python中完成了此操作,没有任何问题.

这是一个示例输入:

Field delimiter = 
quote character = þ

þFieldName1þþFieldName2þþFieldName3þþFieldName4þ
þValue1þþValue2þþValue3þþSomeVery,Very,Very,Large value(5MB or so)þ
...etc...

编辑:
因此,我从头开始创建了一个带分隔符的文件解析器.我对使用此解决方案感到有些厌倦,因为它可能易于出现错误.也不必为这样的任务编写自己的解析器而感到“优雅”或正确.我也有一种感觉,我可能不必为此从头开始编写解析器.

解决方法:

使用File Helpers API.它是.NET和开放源代码.使用编译后的IL代码在强类型对象上设置字段具有极高的性能,并支持流传输.

它支持各种文件类型和自定义分隔符.我用它来读取大于4GB的文件.

如果由于某种原因对您不利,请尝试使用string.split逐行阅读:

public IEnumerable<string[]> CreateEnumerable(StreamReader input)
{
    string line;
    while ((line = input.ReadLine()) != null)
    {
        yield return line.Split('þ');
    }
}

这将为您提供简单的字符串数组,以流畅的方式表示行,甚至您也可以将Linq放入其中;)但是请记住IEnumerable是延迟加载的,因此在您迭代(或导致像ToList / ToArray之类的全负载操作-但是给定文件大小,我认为您不会这样做!).

这是一个很好的示例用法:

using (StreamReader sr = new StreamReader("c:\\test.file"))
{
    var qry = from l in CreateEnumerable(sr).Skip(1)
              where l[3].Contains("something")
              select new { Field1 = l[0], Field2 = l[1] };
    foreach (var item in qry)
    {
        Console.WriteLine(item.Field1 + " , " + item.Field2);
    }
}
Console.ReadLine();

这将跳过标题行,然后从文件的第4个字段包含字符串“ something”的文件中打印出前两个字段.它将执行此操作而不会将整个文件加载到内存中.

上一篇:使用where语句批量更新mysql


下一篇:php操作mongodb基础语法