自定义功能类似于SqlDataReader.Read()

时间:2013-10-30 09:40:49

标签: c# .net

我想创建一个与SqlDataReader.Read()

类似的功能

我正在从.txt / .csv读取一个平面文件,并将其作为数据表返回给我的类处理业务逻辑。这将遍历数据表的各行,并转换数据,写入结构化数据库。我将此结构用于多个导入源。

大文件虽然工作真的很慢。我需要2小时才能完成30 MB的数据,我希望将其缩短到30分钟。朝这个方向迈出的一步是不要将整个文件读入DataTable,而是逐行处理,并防止内存被klogged。

这样的事情是理想的:PSEUDOCODE。

FlatFileReader ffr = new FlatFileReader(); //Set FlatFileParameters
while(ffr.ReadRow(out DataTable parsedFlatFileRow))
{
     //...Business Logic for handling the parsedFlatFileRow
}

如何实施类似.ReadRow(out DataTable parsedFlatFileRow)的方法?


这是正确的方向吗?

foreach(obj in ff.lazyreading()){
    //Business Logic
} 

...

class FlatFileWrapper{

    public IEnumerable<obj> lazyreading(){
        while(FileReader.ReadLine()){ 
            yield return parsedFileLine; 
        }
    } 
}

2 个答案:

答案 0 :(得分:1)

正如蒂姆已经提到的那样,File.ReadLines就是你所需要的:

  

“当您使用ReadLines时,您可以开始枚举   返回整个集合之前的字符串“

您可以创建一个使用该方法的解析器,如下所示:

// object you want to create from the file lines.
public class Foo
{
    // add properties here....
}

// Parser only responsibility is create the objects.
public class FooParser
{
    public IEnumerable<Foo> ParseFile(string filename)
    {
        if(!File.Exists(filename))
            throw new FileNotFoundException("Could not find file to parse", filename);

        foreach(string line in File.ReadLines(filename))
        {
            Foo foo = CreateFoo(line);

            yield return foo;
        }
    }

    private Foo CreateFoo(string line)
    {
        // parse line/create instance of Foo here

        return new Foo {
            // ......
        };
    }
}

使用代码:

var parser = new FooParser();

foreach (Foo foo in parser.ParseFile(filename))
{
     //...Business Logic for handling the parsedFlatFileRow
}

答案 1 :(得分:0)

您可以使用与StreamReader类似的File.ReadLines

foreach(string line in File.ReadLines(path))
{
     //...Business Logic for handling the parsedFlatFileRow
}