Добавление идентичных CSV вместе при удалении заголовков - PullRequest
2 голосов
/ 11 июля 2011

Я хочу добавить 6 CSV, которые имеют идентичные макеты и заголовки вместе.

Я смог сделать это, загрузив каждую из 6 csv в свои отдельные таблицы данных и удалив первую строку каждой таблицы данных.Наконец, я добавил их вместе, используя метод ImportRow.

DataTable table1 = csvToDataTable(@"C:\Program Files\Normalization\Scan1.csv");
DataTable table2 = csvToDataTable(@"C:\Program Files\Normalization\Scan2.csv");
DataTable table3 = csvToDataTable(@"C:\Program Files\Normalization\Scan3.csv");
DataTable table4 = csvToDataTable(@"C:\Program Files\Normalization\Scan4.csv");
DataTable table5 = csvToDataTable(@"C:\Program Files\Normalization\Scan5.csv");
DataTable table6 = csvToDataTable(@"C:\Program Files\Normalization\Scan6.csv");

        foreach (DataRow dr in table2.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table3.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table4.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table5.Rows)
        {
            table1.ImportRow(dr);
        }
        foreach (DataRow dr in table6.Rows)
        {
            table1.ImportRow(dr);
        }

        CreateCSVFile(table1, @"C:\Program Files\Normalization\RackMap.csv");

Я чувствую, что это неуклюже и не очень масштабируемо, но у меня возникли проблемы с заголовками при попытке добавить на уровне CSV.Есть предложения?

TIA

Ответы [ 3 ]

7 голосов
/ 11 июля 2011

Получить DirectoryInfo всех файлов, соответствующих маске *.csv

Создайте цикл for для повторения результатов.

Удалить первую строку при импорте каждого файла.

EDIT:

Если вы просто хотите объединить файлы, а не импортировать их в таблицу данных, вы можете рассматривать их как текстовые файлы. Объедините их, отбрасывая строку заголовка каждый раз. Вот пример:

string myPath = @"K:\csv";

DirectoryInfo csvDirectory = new DirectoryInfo(myPath);
FileInfo[] csvFiles = csvDirectory.GetFiles("*.csv");
StringBuilder sb = new StringBuilder();
foreach (FileInfo csvFile in csvFiles)
    using (StreamReader sr = new StreamReader(csvFile.OpenRead()))
    {
        sr.ReadLine(); // Discard header line
        while (!sr.EndOfStream)
            sb.AppendLine(sr.ReadLine());
    }
File.AppendAllText(Path.Combine(myPath, "output.csv"), sb.ToString());
2 голосов
/ 11 июля 2011

Как предложил JYelton, вам определенно нужно динамически находить все файлы * .csv в вашей папке и выполнять их итерацию (вместо жесткого кодирования 6 имен файлов). С этого момента вы можете рассмотреть такой подход:

  1. Создайте доступный для записи файловый поток для вашего файла-получателя.
  2. Для каждого файла .CSV откройте для него читаемый поток файлов.
  3. Сбросьте строку заголовка каждого файла, прочитав до первого включенного CRLF и включив его, и выбросив эти данные.
  4. Считайте все оставшиеся данные в поток для записи.
  5. Повторите # 2-4 для каждого файла CSV.
  6. Закройте доступный для записи поток, чтобы сохранить завершенный файл.

Этот подход будет учитывать произвольное количество файлов CSV и, вероятно, будет более эффективным с точки зрения производительности, чем работа с DataTables.

Примечание: для краткости и ясности я пропустил некоторые крайние случаи обработки, которые вам понадобятся. Например, как обрабатывать пустой CSV-файл, или файл, который содержит строку заголовка и ничего больше, или файл, у которого нет завершающего CRLF после его последней строки. Разве детали реализации и обработки крайних случаев не интересны? ;)

1 голос
/ 11 июля 2011

Если вы не хотите повторять одинаковые строки, то вы можете создать список хеш-кодов и в цикле найти, если список содержит хеш-код строки.

    List<int> rowHashCodes = new List<int>();
    foreach (DataRow dr in table2.Rows)
    {
        int hash = dr.GetHashCode();
        if (rowHashCodes.Contains(hash))
        {
            // We already have this row
        }
        else
        {
            table1.ImportRow(dr);
            rowHashCodes.Add(hash);
        }
    }

Может быть, это не идеальный способ для производительноститочки зрения, но я надеюсь, что это может решить вашу проблему.

...