12

我正在尝试将 CSV 文件解析为 C# 中的二维数组。我有一个非常奇怪的问题,这是我的代码:

string filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
StreamReader sr = new StreamReader(filePath);
data = null; 
int Row = 0;
while (!sr.EndOfStream)
{
    string[] Line = sr.ReadLine().Split(',');
    if (Row == 0)
    {
        data = new string[Line.Length, Line.Length];
    }
    for (int column = 0; column < Line.Length; column++)
    {
        data[Row, column] = Line[column];
    }
    Row++;
    Console.WriteLine(Row);
}

我的 .csv 文件有 87 行,但在执行中存在一个奇怪的问题,它会完全按照预期将前 15 行读入数据数组,但是当它data[Row, column] = Line[column];第 16 次到达该行时,它似乎刚刚爆发整个循环(sr.EndOfStream不满足条件)并且不再将任何数据读入数据数组。

谁能解释可能发生的事情?

4

5 回答 5

15

上述代码的较短版本:

var filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
var data = File.ReadLines(filePath).Select(x => x.Split(',')).ToArray();

请注意用户的ReadLines而不是,根据MSDN 文档ReadAllLines,它对较大的文件更有效:

使用 ReadLines 时,可以在返回整个集合之前开始枚举字符串集合;使用 ReadAllLines 时,必须等待返回整个字符串数组才能访问该数组。因此,当您处理非常大的文件时,ReadLines 会更有效率。

于 2015-10-21T13:15:10.793 回答
12

您的代码中没有任何内容可以及时从文件中获取行数以使用它。

Line.Length表示您的 csv 中的列数,但看起来您也在尝试使用它来指定文件中的行数。

这应该会给您带来预期的结果:

string filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
StreamReader sr = new StreamReader(filePath);
var lines = new List<string[]>();
int Row = 0;
while (!sr.EndOfStream)
{
    string[] Line = sr.ReadLine().Split(',');
    lines.Add(Line);
    Row++;
    Console.WriteLine(Row);
}

var data = lines.ToArray();
于 2013-09-14T22:12:53.293 回答
3

这与 Pavel 发布的相同,但它忽略了可能导致程序崩溃的空行。

var filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";

string[][] data = File.ReadLines(filepath).Where(line => line != "").Select(x => x.Split('|')).ToArray();
于 2017-04-20T19:56:32.780 回答
0

在不知道 csv 文件的内容的情况下,我会假设错误是由这一行生成的:

if (Row == 0)
{
    data = new string[Line.Length, Line.Length];
}

通过将总行数初始化为 csv 第一行中的列数,您假设行数始终等于列数。

一旦行数大于 csv 第一行的总列数,您将data通过尝试访问不存在的行来超出数组。

您可以通过将您的代码更改data为列表以允许动态添加项目来简化代码:

string filePath = @"C:\Users\Matt\Desktop\Eve Spread Sheet\Auto-Manufacture.csv";
StreamReader sr = new StreamReader(filePath);
List<string> data = new List<string[]>();
int Row = 0;
while (!sr.EndOfStream)
{
    string[] Line = sr.ReadLine().Split(',');
    data.Add(Line);
    Row++;
    Console.WriteLine(Row);
}
于 2013-09-14T22:24:32.933 回答
0

带有打开文件对话框

OpenFileDialog opn = new OpenFileDialog();

        if (opn.ShowDialog() == DialogResult.OK)
        {
           StreamReader sr = new StreamReader(opn.FileName);

           List<string[]> data = new List<string[]>(); 

           int Row = 0;

           while (!sr.EndOfStream)
           {
               string[] Line = sr.ReadLine().Split(',');
               data.Add(Line);
               Row++;
               Console.WriteLine(Row);
           }


        }
于 2017-08-31T18:12:09.073 回答