2013-05-16 1 views
5

Я использую класс TextFieldParser для чтения файла с разделителями-запятыми (.csv). Поля в этом файле заключены в двойные кавычки, такие как "Field1","Field2".TextFieldParser Class

Итак, чтобы прочитать файл, я установил для свойства HasFieldsEnclosedInQuotes объекта TextFieldParser значение true. Но я получаю ошибку MalformedLineException, когда какой-либо из полей содержат двойные кавычки (`" +) в начале

. Пример: ""Field2"with additional" Здесь я должен видеть "Field2" with additional в качестве выходного сигнала

Однако, если " где-либо, кроме первого. положение, то он работает отлично. как линии с "Field2 "with" additional" отлично работает и дает мне Field2 "with" additional как выход.

ли какой-либо один есть такая же проблема? есть ли способ, что я могу решить эту проблему?

Это мой код:

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 

Это мои данные в CSV файле:

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

Добавь свой номер – nmat

+0

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

+0

Нет, у меня нет контроля над этим. – optimusprime

ответ

-1

[Подлинный ответ]

Попробуйте это:

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

} 

Примечание : Я размещаю на C#, так как вопрос все еще b eing с тегом.

Поскольку тег C# отсутствует, обратитесь к http://converter.telerik.com/ за помощью в преобразовании кода в VB.

[Обновлено ответ]

Попытка другой подход (на этот раз, в 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

Нет, я не могу. Потому что в csv есть запятые (,) и кавычки («) тоже являются частью данных. Функция разделения в этом случае не работает. Спасибо, хотя и отправляю код для меня. Было бы совершенно понятно, если бы мои данные не содержали запятая и котировки. – optimusprime

+0

@optimusprime, как насчет сейчас? –

9

Ваш пример ""A" Block" имеет неверный формат CSV; таким образом, TextFieldParser имеет полное право отклонить его. CSV standard говорит:

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" 

Если кодировать данные правильно, то есть ...

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

... TextFieldParser работает нормально и корректно возвращает "A" Block in Building 123.

Итак, первым шагом было бы рассказать парню, производящему файл CSV, для создания действительного CSV-файла вместо чего-то-похожего-CSV-но-isn't.

Если вы не можете сделать это, вы можете захотеть сделать два прохода через файл:

  • исправить файл, преобразовав его в «действительный» CSV файл (например, заменив кавычки не последовало или предшествуют запятой двумя кавычками).
  • Затем TextFieldParser может без проблем проанализировать «действительный» CSV-файл.