Чтение/запись файлов с разделителями CSV/tab в С#

Мне нужно прочитать из файла с разделителями CSV/Tab и записать в такой файл также из .net.

Трудность состоит в том, что я не знаю структуру каждого файла и мне нужно записать файл cvs/tab в datatable, который, похоже, не поддерживает библиотека FileHelpers.

Я уже написал его для Excel с помощью OLEDB, но не могу увидеть способ записи файла табуляции, поэтому вернемся к библиотеке.

Может ли кто-нибудь помочь с предложениями?

Ответы

Ответ 1

Я использовал этот CsvReader, это действительно здорово и хорошо настраивается. Он хорошо себя ведет со всеми видами экранирования для строк и разделителей. Ускорение в других быстрых и грязных реализациях было плохим, но этот lib действительно хорош при чтении. С помощью нескольких дополнительных кодеков вы также можете добавить кеш, если вам нужно.

Письмо не поддерживается, но оно довольно тривиально для реализации. Или вдохните себя из этого кода.

Ответ 3

Вот несколько реализаций CSV-считывателя:

http://www.codeproject.com/KB/database/CsvReader.aspx

http://www.heikniemi.fi/jhlib/ (только одна часть библиотеки, также есть писатель CSV)

Я сомневаюсь, что существует стандартный способ конвертировать CSV в DataTable или базу данных "автоматически", вам нужно написать код для этого. Как это сделать, это отдельный вопрос.

Ответ 4

Вы создадите свой код в коде и, предположив строку заголовка, можете создавать столбцы на основе вашей первой строки в файле. После этого просто нужно будет прочитать файл и создать новые строки на основе данных в нем.

Вы можете использовать что-то вроде этого:

DataTable Tbl = new DataTable();
using(StreamReader sr = new StreamReader(path))
{
  int count = 0;
  string headerRow = sr.Read();
  string[] headers = headerRow.split("\t") //Or ","
  foreach(string h in headers)
  {
    DataColumn dc = new DataColumn(h);
    Tbl.Columns.Add(dc);
    count++;
  }
  while(sr.Peek())
  {
    string data = sr.Read();
    string[] cells = data.Split("\t") 
    DataRow row = new DataRow();
    foreach(string c in cells)
    {
      row.Columns.Add(c);
    }
    Tbl.Rows.Add(row);
  }
}

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

Ответ 5

Вы можете читать и писать csv файл. Это может быть полезно для вас.

передать split char этому параметру "serparationChar"

Пример: -

    private DataTable dataTable = null;
    private bool IsHeader = true;
    private string headerLine = string.Empty;
    private List<string> AllLines = new List<string>();
    private StringBuilder sb = new StringBuilder();
    private char seprateChar = ',';


    public DataTable ReadCSV(string path, bool IsReadHeader, char serparationChar)
    {
        seprateChar = serparationChar;
        IsHeader = IsReadHeader;
        using (StreamReader sr = new StreamReader(path,Encoding.Default))
        {
            while (!sr.EndOfStream)
            {
              AllLines.Add( sr.ReadLine());
            }
            createTemplate(AllLines);
        }

        return dataTable;
    }
    public void WriteCSV(string path,DataTable dtable,char serparationChar)
    {
        AllLines = new List<string>();
        seprateChar = serparationChar;
        List<string> StableHeadrs = new List<string>();
        int colCount = 0;
        using (StreamWriter sw = new StreamWriter(path))
        {
            foreach (DataColumn col in dtable.Columns)
            {
                sb.Append(col.ColumnName);
                if(dataTable.Columns.Count-1 > colCount)
                sb.Append(seprateChar);
                colCount++;
            }
            AllLines.Add(sb.ToString());

            for (int i = 0; i < dtable.Rows.Count; i++)
            {
                sb.Clear();
                for (int j = 0; j < dtable.Columns.Count; j++)
                {
                    sb.Append(Convert.ToString(dtable.Rows[i][j]));
                    if (dataTable.Columns.Count - 1 > j)
                    sb.Append(seprateChar);
                }
                AllLines.Add(sb.ToString());
            }

            foreach (string dataline in AllLines)
            {
                sw.WriteLine(dataline);
            }
        }


    }

    private DataTable createTemplate(List<string> lines)
    {

        List<string> headers = new List<string>();
        dataTable = new DataTable();
        if (lines.Count > 0)
        {
            string[] argHeaders = null;
            for (int i = 0; i < lines.Count; i++)
            {
                if (i > 0)
                {
                    DataRow newRow = dataTable.NewRow();
                    // others add to rows
                    string[] argLines = lines[i].Split(seprateChar);
                    for (int b = 0; b < argLines.Length; b++)
                    {
                        newRow[b] = argLines[b];
                    }
                    dataTable.Rows.Add(newRow);

                }
                else
                {
                    // header add to columns
                    argHeaders = lines[0].Split(seprateChar);
                    foreach (string c in argHeaders)
                    {
                        DataColumn column = new DataColumn(c, typeof(string));
                        dataTable.Columns.Add(column);
                    }
                }

            }

        }
        return dataTable;
    }

Ответ 6

Я нашел лучшее решение

http://www.codeproject.com/Articles/415732/Reading-and-Writing-CSV-Files-in-Csharp

Просто мне пришлось переписать

void ReadTest()
{
    // Read sample data from CSV file
    using (CsvFileReader reader = new CsvFileReader("ReadTest.csv"))
    {
        CsvRow row = new CsvRow();
        while (reader.ReadRow(row))
        {
            foreach (string s in row)
            {
                Console.Write(s);
                Console.Write(" ");
            }
            Console.WriteLine();

            row = new CsvRow(); //this line added
        }
    }
}