2016-09-24 2 views
0

У меня есть CSV файл 20000 строка, которая выглядит (. Он не имеет вертикальные полосы на самом деле, это только для визуального представления каждая строка заканчивается carriage return и значения comma-separated), как это:Проходной табличный файлов 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 | 
| 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 на выходе.

Где я ошибся? Спасибо.

Edit: Вот как фактический 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 
+0

Рассмотрите возможность использования регулярных выражений для этого. – ProXicT

+0

Требуется гений, чтобы написать выражение regurall. Я просто смертный :( –

+0

Почему бы вам не попробовать «Excel Interop libs» –

ответ

1

У меня нет проблем, чтение CSV-файла в 4 раза размера ваших 20000 строк в течение 2 секунд. Я не знаю, что происходит в DoSomething, так что это может быть ваш следующий вызов расследования.

Я внес следующие изменения для решения двух проблем, которые вы описываете.

Во-первых: используйте StringBuilder, чтобы предотвратить создание и отбрасывание большого количества строк в вашей петле.

Второе: Установите Delimiter в Configuration объекте CsvHelper на пространство, но действительно включает запятую вашего заголовка имени поля в этом случае:

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); 

Для 102000 строк выше код работает на моем поле в 1,7 секунды.

+0

'csv.Configuration.Delimiter =" "; // space - спасибо! также запятая в заголовке! ' –

Смежные вопросы