2013-05-16 8 views
5

Sto utilizzando la classe TextFieldParser per leggere il file con valori separati da virgola (.csv). I campi in questo file sono racchiusi tra virgolette doppie come "Field1","Field2".TextFieldParser Class

Quindi, per leggere il file, ho impostato la proprietà TextFieldParser su true. Ma ottengo un errore di MalformedLineException quando uno dei campi contengono virgolette (`" +) in principio

Esempio:. ""Field2"with additional" Qui dovrei vedere "Field2" with additional come uscita

Tuttavia, se " è ovunque tranne che per primo. posizione poi funziona benissimo. come linea con "Field2 "with" additional" opere perfettamente bene e mi dà Field2 "with" additional come output.

non uno ha stesso problema? c'è un modo per risolvere questo problema?

012.

Questo è il mio codice:

Private Sub ReadTextFile(ByVal txtFilePath As String) 
    Dim myReader As tfp = New Microsoft.VisualBasic.FileIO.TextFieldParser(txtFilePath) 
    myReader.Delimiters = New String() {","} 
    myReader.TextFieldType = FileIO.FieldType.Delimited 
    myReader.HasFieldsEnclosedInQuotes = True 
    myReader.TrimWhiteSpace = True 
    Dim currentRow As String() 
    Dim headerRow As Integer = 0 

    While Not myReader.EndOfData 
     Try 
      currentRow = myReader.ReadFields() 

      'Read Header 
      If (headerRow = 0) Then 
       'Do work for Header Row 
       headerRow += 1 
      Else 
       'Do work for Data Row 
      End If 

     Catch ex As Exception 
      Dim errorline As String = myReader.ErrorLine 
     End Try 
    End While 

End Sub 

Questo è il mio dati in file CSV:

 
"Column1","Column2","Column3" 
"Value1","Value2",""A" Block in Building 123" 
+0

Aggiungi il tuo codice per favore – nmat

+0

Sembra un errore o qualcosa del genere. Forse potresti considerare di non avere le doppie virgolette nei tuoi campi se saranno incluse in questo, se questa è una possibilità per te – SysDragon

+0

No, non ne ho il controllo. – optimusprime

risposta

-1

[risposta originale]

Prova questo:

using System; 
using System.IO; 
using System.Linq; 

class Test 
{ 
    static void Main() 
    { 
     var file = "Test.txt"; 

     var r = File.ReadAllLines(file) 
      .Select((i, index) => new { Line = index, Fields = i.Split(new char[] { ',' }) }); 

     // header 
     var header = r.First(); 

     // do work for header 
     for (int j = 0; j < header.Fields.Count(); j++) 
     { 
      Console.Write("{0} ", header.Fields[j].Substring(1, header.Fields[j].Length-2)); 
     } 
     Console.WriteLine(); 

     var rows = r.Skip(1).ToList(); 

     // do work for rows 
     for (int i = 0; i < rows.Count; i++) 
     { 
      for (int j = 0; j < rows[i].Fields.Count(); j++) 
      { 
       Console.Write("{0} ", rows[i].Fields[j].Trim(new[] { '"' })); 
      } 
      Console.WriteLine(); 
     } 
    } 

} 

Nota : Sto postando in C# poiché la domanda è ancora b eing ha taggato con esso.

Man mano che il tag C# è scomparso, fare riferimento a http://converter.telerik.com/ per assistenza nella conversione del codice in VB.

[risposta Aggiornamento]

provare un approccio diverso (questa volta, in VB.Net):

Imports System 
Imports System.IO 
Imports System.Linq 

Class Test 
    Public Shared Sub Main() 
     Dim file__1 = "Test.txt" 

     Dim r = File.ReadAllLines(file__1).[Select](Function(i, index) New With { _ 
      .Line = index, _ 
      .Fields = i.Substring(1, i.Length - 2).Split(New String() {""","""}, StringSplitOptions.None) _ 
     }) 

     ' header 
     Dim header = r.First() 

     ' do work for header 
     For j As Integer = 0 To header.Fields.Count() - 1 
      Console.Write("{0} ", header.Fields(j)) 
     Next 
     Console.WriteLine() 

     Dim rows = r.Skip(1).ToList() 

     ' do work for rows 
     For i As Integer = 0 To rows.Count - 1 
      For j As Integer = 0 To rows(i).Fields.Count() - 1 
       Console.Write("{0} ", rows(i).Fields(j)) 
      Next 
      Console.WriteLine() 
     Next 
    End Sub 
End Class 
+1

No i Can not. Perché in csv ci sono le virgole (,) e le virgolette (") sono anche parte dei dati. La funzione Split non funziona in quei casi. Grazie per aver pubblicato un codice per me. Avrebbe perfettamente senso se i miei dati non avessero contenuto virgola e virgolette – optimusprime

+0

@optimusprime, che ne dici adesso? –

9

Il vostro esempio è ""A" Block" CSV malformati; quindi, TextFieldParser ha tutto il diritto di rifiutarlo. Il CSV standard dice:

7. If double-quotes are used to enclose fields, then a double-quote 
    appearing inside a field must be escaped by preceding it with 
    another double quote. For example: 

    "aaa","b""bb","ccc" 

Se codificare i dati in modo corretto, vale a dire, ...

"Column1","Column2","Column3" 
"Value1","Value2","""A"" Block in Building 123" 

... TextFieldParser funziona bene e correttamente restituisce "A" Block in Building 123.

Quindi, il primo passo sarebbe dire al ragazzo che produce il file CSV per creare un file CSV valido invece di qualcosa-che-sembra-come-CSV-ma-non-è.

Se non è possibile fare questo, si potrebbe desiderare di fare due passate attraverso il file:

  • correggere il file convertendolo in un file CSV "valido" (ad esempio sostituendo le citazioni non seguito o preceduto da una virgola di due virgolette).
  • Quindi, TextFieldParser è in grado di analizzare il file CSV "valido" senza problemi.