2010-06-28 18 views
13

Potrzebuję czytać z pliku CSV/Tab i zapisywać do takiego pliku również z .net.Czytanie/pisanie plików rozdzielanych CSV/tabulatorami w języku C#

Trudność polega na tym, że nie znam struktury każdego pliku i muszę zapisać plik cvs/tab do elementu datatable, który wydaje się nie obsługiwać biblioteki FileHelpers.

Napisałem już dla programu Excel przy użyciu OLEDB, ale naprawdę nie widzę sposobu na zapisanie pliku tabulacji, więc wrócę do biblioteki.

Czy ktoś może pomóc z sugestiami?

Odpowiedz

7

Użyłem tego CsvReader, jest naprawdę świetny i dobrze konfigurowalny. Zachowuje się dobrze przy wszelkiego rodzaju ucieczkach na struny i separatory. Ucieczka w innych szybkich i brudnych implementacjach była słaba, ale ta lib jest naprawdę świetna w czytaniu. Z kilkoma dodatkowymi codelinami możesz także dodać pamięć podręczną, jeśli potrzebujesz.

Pisanie nie jest obsługiwane, ale jest dość trywialne, aby się zrealizować. Lub zainspiruj się od this code.

+0

Niestety ... wydaje mi się to trochę odległe, ale domyślam się, że moim głównym zadaniem przy pisaniu plików CSV jest ograniczanie ciągów znaków (minęło trochę czasu, odkąd musiałem tworzyć pliki CSV). –

+0

Dodałem link do pisania CSV, możesz zamienić niektóre stałe ciągi na preferowane ograniczniki i powinno być dobrze. Czytanie jest o wiele bardziej skomplikowane niż pisanie ... – jdehaan

+0

Jednak pisanie plików CSV, które zawierają arbitralne ciągi, nie jest trywialne. Zapamiętaj sekwencje ucieczki! –

1

Oto kilka CSV implementacje czytnika:

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

http://www.heikniemi.fi/jhlib/ (tylko jedna część biblioteki obejmuje pisarz CSV zbyt)

Wątpię, jest to standardowy sposób przekonwertować plik CSV do DataTable lub bazy danych "automatycznie", będziesz musiał napisać kod, aby to zrobić. Jak to zrobić, to osobne pytanie.

+2

Dlaczego po prostu nie użyć tego, który jest dostarczany z platformą .NET? –

1

Będziesz tworzyć dane w kodzie, a (przypuszczając wiersz nagłówka) można tworzyć kolumny na podstawie pierwszego wiersza w pliku. Po tym będzie po prostu kwestia odczytywania pliku i tworzenia nowych wierszy na podstawie zawartych w nim danych.

Można użyć coś takiego:

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

Powyższy kod nie został skompilowany, więc może mieć pewne błędy, ale powinno Ci na dobrej drodze.

+0

Twój podzielony kod jest niepoprawny, ponieważ możesz mieć demliniator w cytowanym ciągu. –

+0

@ Jonathan Allen: Tak, rzeczywiście możesz. Nie został zaprojektowany, aby być pełnym rozwiązaniem ... tylko wskazówką na właściwy tor. – AllenG

13

. NET zawiera parsektor plików z ograniczeniami CSV/tab o nazwie klasa TextFieldParser.

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx

Obsługuje pełną RFC dla plików CSV i naprawdę dobrej raportowania błędów.

+5

Musisz pokochać, że ogólne klasy narzędzi są w Microsoft.VisualBasic.dll. – MgSam

+0

Niestety, nie wydaje się, aby to oznaczało twoja własność owijania tekstem, zakłada, że ​​jest to podwójny cytat i pozwala tylko włączyć/wyłączyć. – ChrisProsser

+1

Czy możesz podać szybki przykład? Linki nie są wystarczającymi odpowiedziami. Jeśli to zepsuje, ta odpowiedź jest bezużyteczna dla każdego pracownika Google. –

0

Możesz odczytać i zapisać plik csv. Może to być pomocne.

wprost Podział char do tego parametru "serparationChar"

przykład: -

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; 
    } 
0

znalazłem najlepsze rozwiązanie

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

Właśnie miałem do ponownego zapisu

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 
     } 
    } 
} 
Powiązane problemy