2011-11-23 95 views
2

大分隔符的文本文件,我正忙着與一個應用讀取空間分隔的日誌文件從5MB至1GB +大小,然後將此信息存儲到MySQL數據庫,供以後使用時,根據打印報告根據文件中包含的信息。我嘗試/發現的方法,但速度很慢。的讀取和解析VB.net

我做錯了什麼?還是有更好的方式來處理非常大的文本文件?

我使用textfieldparser如下嘗試:

Using parser As New TextFieldParser("C:\logfiles\testfile.txt") 
    parser.TextFieldType = FieldType.Delimited 
    parser.CommentTokens = New String() {"#"} 
    parser.Delimiters = New String() {" "} 
    parser.HasFieldsEnclosedInQuotes = False 
    parser.TrimWhiteSpace = True 
    While Not parser.EndOfData 
     Dim input As String() = parser.ReadFields() 
     If input.Length = 10 Then 
      'add this to a datatable 
     End If 
    End While 
End Using 

這工作,但對於較大的文件很慢。

Function GetSquidData(ByVal logfile_path As String) As System.Data.DataTable 
    Dim myData As New DataSet 
    Dim strFilePath As String = "" 
    If logfile_path.EndsWith("\") Then 
     strFilePath = logfile_path 
    Else 
     strFilePath = logfile_path & "\" 
    End If 
    Dim mySelectQry As String = "SELECT * FROM testfile.txt WHERE Client_IP <> """"" 
    Dim myConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFilePath & ";Extended Properties=""text;HDR=NO;""") 
     Dim dsCmd As New System.Data.OleDb.OleDbDataAdapter(mySelectQry, myConnection) 
     dsCmd.Fill(myData, "logdata") 
     If Not myConnection.State = ConnectionState.Closed Then 
      myConnection.Close() 
     End If 
    Return myData.Tables("logdata") 
End Function 

Schema.ini文件:

我然後使用結合一個schema.ini文件寫到預先目錄中的OLEDB連接到文本文件按照以下函數試圖

[testfile.txt] 
Format=Delimited() 
ColNameHeader=False 
Col1=Timestamp text 
Col2=Elapsed text 
Col3=Client_IP text 
Col4=Action_Code text 
Col5=Size double 
Col6=Method text 
Col7=URI text 
Col8=Ident text 
Col9=Hierarchy_From text 
Col10=Content text 

任何人有任何想法如何更快地閱讀這些文件?

CNC中 更正上面代碼中的

+0

你可能會考慮使用[LOGPARSER(http://en.wikipedia.org/wiki/Logparser),而不是試圖實現它自己。 – AakashM

+1

這些方法是否一次讀取整個文件?如果你看到你的程序的內存是否超過了你讀取的文件的大小(500MB-1GB)?如果是這樣,您可能需要使用一種讀取文件的方法,該文件一次只能讀取一行文件。 –

+0

@AakashM謝謝你一定會考慮到這一點。 –

回答

2

有兩個潛在的慢操作有:

  • 文件閱讀
  • 插入大量數據到數據庫

將它們分開,並測試其花費大部分時間。即編寫一個簡單地讀取文件的測試程序,以及另一個只需插入大量記錄的測試程序。看哪一個最慢。

一個問題可能是您正在閱讀的整個文件到內存?

嘗試通過符合的流線閱讀。這裏是一個code example copied from MSDN

Imports System 
Imports System.IO 

Class Test 
    Public Shared Sub Main() 
     Try 
      ' Create an instance of StreamReader to read from a file. 
      ' The using statement also closes the StreamReader. 
      Using sr As New StreamReader("TestFile.txt") 
       Dim line As String 
       ' Read and display lines from the file until the end of 
       ' the file is reached. 
       Do 
        line = sr.ReadLine() 
        If Not (line Is Nothing) Then 
         Console.WriteLine(line) 
        End If 
       Loop Until line Is Nothing 
      End Using 
     Catch e As Exception 
      ' Let the user know what went wrong. 
      Console.WriteLine("The file could not be read:") 
      Console.WriteLine(e.Message) 
     End Try 
    End Sub 
End Class 
+0

感謝您的回答MarkJ,我無法打開你所提供的鏈接:(想我的ISP今天可能有一些問題... 我已經嘗試過使用streamreader.readline函數,但沒有看到它造成很大的差異(也與更大的文件,我得到一個system.outofmemory異常)。這是你的建議嗎? –

+0

@DonnavandeGroot我已將鏈接中的代碼示例複製到我的答案中。我還編輯了我的答案,建議您進行一些實驗,以確定文件讀取或數據庫插入是否是瓶頸。這就是我會做第一 – MarkJ

+0

感謝您更新您的文章:)我嘗試使用流式閱讀器,但我收到system.outofmemory異常:(此外,我已經完全拆分作業,它絕對是非常需要的文件的閱讀long –

-2

一個錯字從我頭上ID頂說嘗試教學貫徹某種線程的傳播工作量。

+1

最有可能導致速度問題的原因是磁盤活動,而不是CPU限制,所以線程最可能沒有幫助。 –

+0

感謝您的意見,但我不得不同意上述的CodyC。除非有可能將文件分割成x行段,然後讓不同的線程處理文件的每個段?這甚至可能/可行嗎? [需要通過線分割但正如每一行是一個完整的記錄和無法風險具有不完整的線丟失數據] –