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

标签 c# parsing bulk csv

我一直在尝试处理一些具有非标准定界符(不是逗号/引号或制表符定界)的定界文本文件。分隔符是随机的 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 是延迟加载的,因此在迭代之前不要关闭或更改 StreamReader(或导致像 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”。它会在不将整个文件加载到内存的情况下执行此操作。

关于c# - 在 C# 中使用自定义分隔符和一些非常非常大的字段值解析文本的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/339496/

相关文章:

c# - Entity Framework 6 Code First 函数映射

c# - 给定一个字符串列表,分配到两个 100 个字符的字段中

java - 解析数据时出错 org.json.JSONException : End of input at character 0 of

parsing - 如何测试不符合 Instaparse 语法(Clojure)的文本?

ffmpeg - 批量修剪视频 : remove last x seconds from video

c# - 在 C# 中开始循环之前将项目添加到集合中

c# - 关于正则表达式的实现

java - Jsoup 正在转义 iframe 的内容

linux - 重命名具有连续扩展名的文件

sql - SQL Server 中的批量插入