2013-05-16 45 views
5

我正在使用TextFieldParser類讀取逗號分隔值(.csv)文件。此文件中的字段用雙引號括起來,如"Field1","Field2"TextFieldParser類

因此,要讀取文件,我已將TextFieldParser對象的HasFieldsEnclosedInQuotes屬性設置爲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(); 
     } 
    } 

} 

注:因爲問題仍然是b,所以我在C#中發佈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那樣的東西,但是不是。

如果你不能做到這一點,你可能想通過文件進行兩遍:

  • 通過更換引號將其轉換爲一個「有效」的CSV文件(例如修復文件不之後或之前由兩個逗號逗號)。
  • 然後,TextFieldParser可以毫無困難地解析「有效的」CSV文件。