循环通过表格csv文件

时间:2016-09-24 10:27:07

标签: c# csv

我有一个20,000行的csv文件看起来(它实际上没有垂直条,这只是用于直观表示。每行以carriage return结尾,值为comma-separated),如下所示:< / p>

| Location,  | Light, | Proximity, | Ax,                 | Ay,                 | Az,                | Gx,                | Gy,                 | Gz                  |
|------------|--------|------------|---------------------|---------------------|--------------------|--------------------|---------------------|---------------------|
| SidePocket | 2.0    | 0.0        | -1.1259307861328125 | -10.622817993164063 | 0.8393707275390625 | 0.7456817626953125 | -2.3446502685546875 | -0.6551361083984375 |
| HandBag    | 2.0    | 0.0        | -1.1259307861328125 | -10.622817993164063 | 0.8393707275390625 | 0.8383636474609375 | -3.1872711181640625 | -0.064971923828125  |
| SidePocket | 2.0    | 0.0        | 0.5566253662109375  | -9.675201416015625  | 1.7905426025390625 | 0.8383636474609375 | -3.1872711181640625 | -0.064971923828125  |
| SidePocket | 2.0    | 0.0        | 0.5566253662109375  | -9.675201416015625  | 1.7905426025390625 | 0.170440673828125  | -2.976348876953125  | 0.05218505859375    |
| BackPocket | 2.0    | 0.0        | -0.3665771484375    | -9.739242553710938  | 2.12567138671875   | 0.170440673828125  | -2.976348876953125  | 0.05218505859375    |
| SidePocket | 2.0    | 0.0        | -0.3665771484375    | -9.739242553710938  | 2.12567138671875   | -0.1981201171875   | -1.846099853515625  | 0.290802001953125   |
| Ear        | 2.0    | 0.0        | -0.490264892578125  | -9.91455078125      | 1.34954833984375   | -0.1981201171875   | -1.846099853515625  | 0.290802001953125   |

我想要的东西可以帮助我根据列标题遍历列的所有行并进行一些计算。我尝试使用CsvHelper即。

private void btnBrowse_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog openFileDialog = new OpenFileDialog();
    if (openFileDialog.ShowDialog() == true)
        textReader = File.ReadAllText(openFileDialog.FileName);
    stringParse = new StringReader(textReader);
    txtOutput.Text = "";
}

private void btnParse_Click(object sender, RoutedEventArgs e)
{
    var csv = new CsvReader(stringParse);
    while( csv.Read() )
    {               
        var stringField = csv.GetField<string>( "Location" );
        txtOutput.Text += DoSomething(stringField.ToString()) + "\n";
    }
}

我面临的问题是:

  • 首先,这非常非常慢。暂停我的小型WPF应用程序。
  • 其次,它不会返回预期字段的值。它将整个csv转储到输出中。

我在哪里弄错了? 感谢。

编辑:以下是实际csv的外观:

Location, Light, Proximity, Ax, Ay, Az, Gx, Gy, Gz
"SidePocket" 2.0 0.0 -1.1259307861328125 -10.622817993164063 0.8393707275390625 0.7456817626953125 -2.3446502685546875 -0.6551361083984375
"HandBag" 2.0 0.0 -1.1259307861328125 -10.622817993164063 0.8393707275390625 0.8383636474609375 -3.1872711181640625 -0.064971923828125
"SidePocket" 2.0 0.0 0.5566253662109375 -9.675201416015625 1.7905426025390625 0.8383636474609375 -3.1872711181640625 -0.064971923828125

1 个答案:

答案 0 :(得分:1)

我在2秒内读取2万行大小的4倍的csv文件没有问题。我不知道DoSomething中发生了什么,所以这可能是你的下一次调查。

我做了以下更改,以解决您描述的两个问题。

首先:使用StringBuilder来防止在循环中创建和丢弃大量字符串。

第二步:将CsvHelper的Delimiter对象中的Configuration设置为空格,但在这种情况下请包含标题字段名称的逗号:

var sw = new Stopwatch();
sw.Start();
using(var csv = new CsvReader(new StreamReader(@"csv-test.txt")))
{
    csv.Configuration.Delimiter=" "; // space

    var sb = new StringBuilder();

    while (csv.Read())
    {
        var stringField = csv.GetField<string>("Location,"); // the comma is relevant
        // or use sb.AppendFormat("{0}\n", DoSomething(stringField));
        sb.AppendLine(stringField);
    }
    txtOutput.Text = sb.ToString();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

对于102,000行以上代码在我的盒子上运行1,7秒。