Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C语言处理大型文本文件#_C#_.net_String_C# 4.0_.net 4.0 - Fatal编程技术网

C# 用C语言处理大型文本文件#

C# 用C语言处理大型文本文件#,c#,.net,string,c#-4.0,.net-4.0,C#,.net,String,C# 4.0,.net 4.0,我有4GB+文本文件(csv格式),我想用c#中的linq处理这个文件 我在加载csv并转换为类之后运行复杂的linq查询 但文件大小是4gb,尽管应用程序内存是文件大小的两倍 如何处理(linq和新结果)大文件 谢谢您可以逐行读取和处理文件,而不是将整个文件加载到内存中 using (var streamReader = new StreamReader(fileName)) { string line; while ((line = streamReader.ReadLine

我有4GB+文本文件(csv格式),我想用c#中的linq处理这个文件

我在加载csv并转换为类之后运行复杂的linq查询

但文件大小是4gb,尽管应用程序内存是文件大小的两倍

如何处理(linq和新结果)大文件


谢谢

您可以逐行读取和处理文件,而不是将整个文件加载到内存中

using (var streamReader = new StreamReader(fileName))
{
    string line;
    while ((line = streamReader.ReadLine()) != null)
    {
        // analize line here
        // throw it away if it does not match
    }
}
[编辑]


如果您需要对文件中的数据运行复杂的查询,正确的做法是将数据加载到数据库中,让DBMS负责数据检索和内存管理。

我认为这是一个好方法。。。

如果您使用的是.NET 4.0,那么您可以使用并编写一个方法,该方法返回一个IEnumerable行对一行,并使下面这样的代码成为可能

from record in GetRecords("myFile.csv",new []{"Foo","Bar"},new[]{","})
where record.Foo == "Baz"
select new {MyRealBar = int.Parse(record.Bar)
将CSV投影到粘土对象序列中的方法可以创建为:

 private IEnumerable<dynamic> GetRecords(
                    string filePath,
                    IEnumerable<string> columnNames, 
                    string[] delimiter){
            if (!File.Exists(filePath))
                yield break;
            var columns = columnNames.ToArray();
            dynamic New = new ClayFactory();
            using (var streamReader = new StreamReader(filePath)){
                var columnLength = columns.Length;
                string line;
                while ((line = streamReader.ReadLine()) != null){
                    var record = New.Record();
                    var fields = line.Split(delimiter, StringSplitOptions.None);
                    if(fields.Length != columnLength)
                        throw new InvalidOperationException(
                                 "fields count does not match column count");
                    for(int i = 0;i<columnLength;i++){
                        record[columns[i]] = fields[i];
                    }
                    yield return record;
                }
            }
        }
private IEnumerable GetRecords(
字符串文件路径,
IEnumerable列名称,
字符串[]分隔符){
如果(!File.Exists(filePath))
屈服断裂;
var columns=columnNames.ToArray();
动态新=新工厂();
使用(var streamReader=newstreamreader(filePath)){
var columnLength=columns.Length;
弦线;
而((line=streamReader.ReadLine())!=null){
var record=New.record();
var fields=line.Split(分隔符,StringSplitOptions.None);
如果(fields.Length!=columnLength)
抛出新的InvalidOperationException(
“字段计数与列计数不匹配”);

对于(int i=0;i如果所有文本都在一行中而没有回车符,那该怎么办?@Cody-我假设csv文件不是一行文件。然后您将整个行作为字节流而不是行流进行处理。@Cody那么这是一条记录,可能需要一次处理,因为您无法预先知道是什么字段将出现在lin查询中,或者使用了一个不寻常的记录分隔符,OP很可能会包括,因为这是一个关键的细节,我应该将所有数据加载到内存中,以便运行linq查询并创建新结果?您使用的是.NET的哪个版本?问题是这个读取字节500MB,但内存2GB感谢您的建议,我尝试了这个解决方案在上,但速度非常慢,并且有相同的内存问题。@oguzh4n哦,我谨慎地没有考虑速度,因为你在帖子中没有提到。我更喜欢可读性(在呼叫站点的例子中)任何一天都可以超速。关于内存问题。如果你能更精确地描述这些问题,它们可以被修复。一次(一点)不必保存一行以上的文本文件和一个粘土对象,所以上面草稿中的任何内存问题都可以被修复