【问题标题】:How do I split a line of text and assign the result to a multi-dimensional array?如何拆分一行文本并将结果分配给多维数组?
【发布时间】:2012-12-26 08:05:05
【问题描述】:

我正在尝试读取一个由管道分隔的充满医疗记录的文本文件。大约有 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[,]'

【问题讨论】:

  • 你为什么要为myArray声明一个二维数组?
  • @Oded 我认为最终的数组是二维的,即。 20 列和 X 数百万行?也许我做错了?
  • 就像 SLaks 说的,你想要一个 List。你不知道文件有多少行,所以声明一个数组来保存记录是没有意义的。
  • @phan - 好的,但是您正在尝试将 维数组分配给 myArray = strlFileLine; 中的 二维 维数组。
  • 这段代码有很多问题... (1) 使用单个using 语句,您只有一个资源; (2) 使用List<>,而不是数组,(3) 进行一些错误处理,否则如果文件不存在,您的应用程序将崩溃; (4) 读取while中的字符串,检查是否不为null而不是EndOfStream冗余调用

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


【解决方案1】:

如果您想修改它,请使用List<string[]>,数组是不可变的。您也可以使用File.ReadLines,它比StreamReader 更舒服(恕我直言):

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% 的列表。

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

【讨论】:

  • 因为有数百万行我被告知最好使用 StreamReader。当您的代码编译并运行时,对于您的代码行,我在 mscorlib.dll 中收到错误“System.OutofMemoryException”。
  • 好吧,如果这是一个问题,您的代码也将难以将其读入数组。这样所有数据都在内存中两次(有点),一次作为文件,一次作为数组列表。您是否有足够的记忆力可以一次将其全部存储在内存中,您是否需要一次全部。
  • +1 @TonyHopkinson。确切地。为什么需要在内存中同时拥有数百万条记录?你最终对他们做了什么?
  • “最终,我想分析数据并计算生活在特定邮政编码中的患者的平均年龄。另外,计算计数、最小值、最大值、中位数等”然后你应该放入数据库,然后对数据运行查询。
  • @phan: File.ReadLines 在内部使用 StreamReader 一次读取一行,而 File.ReadAllLines 一次将所有内容读入内存。
【解决方案2】:

试试这个:

        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('|')))
            }
        }

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

【讨论】:

  • 与上述相同的问题。文本文件有 1GB 大,所以我遇到了内存问题。请参阅我对 Tim Schmelter 的评论。
【解决方案3】:

借用了 Alexander Balte 的开头。

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
}

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2015-11-12
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 2019-10-11
    相关资源
    最近更新 更多