2012-05-17 27 views
2

我正在研究一個程序,您可以從csv文件(它最初解析標題)中選擇標題,並且我希望用戶能夠獲取列的數據,而無需讀取整個文件(創建一個字符串數組的列表並提取信息的字符串數組索引,這很簡單)。通過CSV尋找具有特定標題的列

有沒有辦法可以使用seek來做到這一點?也許搜索一個字符串(這將是頭),並獲得其列內的信息。

這是在情況下,它可以幫助getHeader功能...

private string[] getHeader(string path)//gets the headers from the file path specified. 
    {   
     List<string> row = new List<string>(); 

     using (StreamReader readFile = new StreamReader(path)) 
     {   
      row = (readFile.ReadLine().Split(',').ToList());     
     } 

     return row.ToArray(); 

    } 

(在列出和數組是那裏只是爲了避開最初設置大小的數組...)

謝謝!

+0

目前還不清楚你想達到什麼目標......你能更好地解釋你的目標是什麼嗎? – aleroot

+0

Split無論如何返回一個數組,所以你可以安全地返回readFile.ReadLine()。Split(',')'。至於列的東西,除非你有固定寬度的列,否則我會想象你能做的最好的只是讀取文件。 –

+0

需要注意的一件事是,如果數據包含逗號並且您必須使用引號分隔的文本,則調用Split將不起作用。在這種情況下,你實際上必須做一些解析。 – JamieSee

回答

2

不可能。

尋求可以在文件中確定位置。如果您有一個長度記錄長度很長且記錄較少的固定長度記錄(SDF/COBOL)文件,這將是一個好主意。

不幸的是,.csv的定義是可變長度記錄。您只能通過在記錄末尾點擊cr/lf來確定一條記錄停止和啓動的位置。

即使使用大多數固定記錄格式,這也不是一個好主意。由於緩衝,操作系統將讀取整個文件,因爲您會預先尋找更少的數量,然後操作系統已經預裝。

我可以看到你爲什麼想要這樣做;直觀地說,聽起來它會更快。雖然你應該始終牢記設計你的代碼,但這是低級的,足以成爲'過早優化' - 谷歌。基本上,你必須向自己證明它的寫作運行緩慢,然後,當你發現它對功能有很大的阻礙時,你可以優化。

不要自己解析它!

MS有一個組件。 Microsoft.VisualBasic.FileIO.TextFieldParser。是的,你可以使用它與C#(即使下面的示例是在VB中,你可以找出你需要做什麼)。不要太自豪,不要引用VB。你的口袋裏有時間和金錢,不能說'我不會用一根10英尺的杆子碰到任何VB'。程序集已經在您的目標PC上進行了更改。只關心如果你有程序安裝包下載大小問題,或者正在部署到非PC平臺。

Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(CSVPath) 

     Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited 
     Reader.Delimiters = New String() {","} 
     Reader.TrimWhiteSpace = True 
     Reader.HasFieldsEnclosedInQuotes = True 

     While Not Reader.EndOfData 
      Try 
       Dim st2 As New List(Of String) 
       st2.addrange(Reader.ReadFields()) 
       If iCount > 0 Then ' ignore first row = field names 
        Dim p As New clsPerson 
        p.CSVLine = st2 
        While p.CSVLine.Count < 15 
         p.CSVLine.Add("") 
        End While 
        p.FirstName = st2(1).Trim 
        If st2.Count > 2 Then 
         p.MiddleName = st2(2).Trim 
        Else 
         p.MiddleName = "" 
        End If 
        p.LastNameSuffix = st2(0).Trim 
        If st2.Count >= 6 Then 
         p.TestCase = st2(5).Trim 
        End If 
        If st2(3) > "" Then 
         p.CertsFromCase.Add(st2(3)) 
        End If 
        cases.Add(p) 
       Else 
        stFirstRow = CatLine(st2.ToArray) 
        Dim st3(6) As String 
        For kk As Integer = 0 To Math.Min(st2.Count - 1, 5) 
         st3(kk) = st2(kk) 
        Next 
        If 0 = InStr(st3(0), "Last Name", CompareMethod.Text) Or _ 
        0 = InStr(st3(1), "First Name", CompareMethod.Text) Or _ 
        0 = InStr(st3(2), "Middle Name", CompareMethod.Text) Or _ 
        0 = InStr(st3(3), "Policy", CompareMethod.Text) Or _ 
        0 = InStr(st3(5), "Test Case", CompareMethod.Text) Then 
         stFirstRow = "Last Name,First Name,Middle Name,Policy,,Test Case #" & vbCrLf & stFirstRow 
        End If 
       End If 
      Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException 
       MsgBox("Line " & ex.Message & " is not valid and will be skipped.") 
      End Try 
      iCount += 1 
     End While 
    End Using 
+0

謝謝。我意識到我沒有完全理解如何尋找工作,因爲它被一個同事錯誤地向我解釋... – Axxelsian

+0

很酷!祝你好運。 – FastAl