如何拆分文本行并将结果分配给多维数组?

时间:2013-01-11 17:15:46

标签: c# multidimensional-array visual-studio-2012

我正在尝试阅读一个充满由管道分隔的医疗记录的文本文件。大约有20列数据和数百万行。文本文件的大小约为1GB。

第一步是读取数据。这是我的代码:

private void button1_Click(object sender, EventArgs e)
    {
        string strFilePath = @"abcrecords.txt";
        string[,] myArray;

        using (FileStream fs = new FileStream(strFilePath, FileMode.Open))
        using (StreamReader rdr = new StreamReader(fs))
        {
            while (!rdr.EndOfStream)
            {
                string[] strFileLine = rdr.ReadLine().Split('|');
                {
                    myArray = strFileLine;
                }
            }
        }
    }

如何将分割线(包含20个元素)的结果放入myArray的第一行。然后将每个新的分割线添加到myArray?现在,我收到错误:

  

错误无法将类型'string []'隐式转换为'string []'

3 个答案:

答案 0 :(得分:1)

如果要修改它,请使用List<string[]>,数组是不可变的。你也可以使用File.ReadLines作为StreamReader(imho):

更舒服
List<string[]> allLines = File.ReadLines(path)
    .Select(l => l.Split('|').ToArray())
    .ToList();

请注意,上面是Linq查询,需要添加using System.Linq

关于我的方法的内存消耗的最后注释。 File.ReadLines在引擎盖下使用StreamReader,一次读取一行,而不是File.ReadAllLines,它同时读取所有内容,但您也可以进一步改进此方法:

查看我自己的相关问题:High memory consumption with Enumerable.Range?

因此,您可以先读取行数,以正确的大小初始化列表:

int count = File.ReadLines(path).Count();
var allLines = new List<string[]>(count);
var lines = File.ReadLines(path).Select(l => l.Split('|').ToArray());
allLines.AddRange(lines);

否则,由于来自List.Add的大小算法加倍,您可能会以一个需要比所需内存多100%的内存的列表结束。

但你应该考虑改用数据库。

答案 1 :(得分:1)

试试这个:

        File.ReadAllLines("abcrecords.txt").Select(x => x.Split('|')).ToArray();

<强>更新

因为文件很大,你可以使用:

        var result = new List<string[]>();
        using (FileStream fs = new FileStream(strFilePath, FileMode.Open))
        using (StreamReader rdr = new StreamReader(fs))
        {
            while (!rdr.EndOfStream)
            {
                result.Add(rdr.ReadLine().Split('|')))
            }
        }

但将这样的大对象存储在内存中会非常昂贵。

答案 2 :(得分:0)

借用亚历山大·巴尔特的开始。

using (FileStream fs = new FileStream("", FileMode.Open))
{
  using (StreamReader rdr = new StreamReader(fs))
  {
    while (!rdr.EndOfStream)
    {
      DoSomethingWith(rdr.ReadLine().Split('|')));
    }
  }
}
void DoSomethingWith(String[] argColumns)
{
  // on y va
}