的读取和解析VB.net

问题描述:

大分隔符的文本文件,我正忙着与一个应用读取空间分隔的日志文件从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谢谢你一定会考虑到这一点。 –

有两个潜在的慢操作有:

  • 文件阅读
  • 插入大量数据到数据库

将它们分开,并测试其花费大部分时间。即编写一个简单地读取文件的测试程序,以及另一个只需插入大量记录的测试程序。看哪一个最慢。

一个问题可能是您正在阅读的整个文件到内存?

尝试通过符合的流线阅读。这里是一个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 –

一个错字从我头上ID顶说尝试教学贯彻某种线程的传播工作量。

+1

最有可能导致速度问题的原因是磁盘活动,而不是CPU限制,所以线程最可能没有帮助。 –

+0

感谢您的意见,但我不得不同意上述的CodyC。除非有可能将文件分割成x行段,然后让不同的线程处理文件的每个段?这甚至可能/可行吗? [需要通过线分割但正如每一行是一个完整的记录和无法风险具有不完整的线丢失数据] –