2011-11-23 6 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 

누구나 이러한 파일을 더 빨리 읽을 수있는 방법이 있습니까?

-edit-

은 작업 부하를 확산 스레딩 어떤 종류의 impelement하려고 말 내 머리 ID의 정상에서

+0

입니다 (http://en.wikipedia.org/wiki/Logparser) 오히려 스스로를 구현하는 것보다. – AakashM

+1

이 방법들은 전체 파일에서 동시에 읽습니까? 프로그램의 메모리를 보면, 읽고있는 파일의 크기 (500MB-1GB)를 초과하여 촬영하고 있습니까? 그렇다면 아마 한 번에 한 줄씩 파일을 읽을 수있는 파일을 읽는 방법을 사용해야합니다. –

+0

@AakashM 감사합니다. –

답변

2

이 두 시간이 걸리는 작업이 있습니다

  • 파일 가장 많은 시간이 걸리는

그들을 분리하고 테스트 DB에 데이터를 많이 삽입

  • 읽고. 나는. 단순히 파일을 읽는 하나의 테스트 프로그램을 작성하고, 많은 레코드를 삽입하는 테스트 프로그램을 작성하십시오. 어느 것이 가장 느린 지보십시오.

    하나의 문제는 전체 파일을 메모리로 읽는 것일 수 있습니다.

    한 줄씩 스트림으로 읽으십시오. 여기에 당신은 [LOGPARSER] 사용으로 볼 수있는 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

    위의 코드에 오타가 수정되었습니다.

    +1

    속도 문제를 일으키는 가장 큰 원인은 디스크 활동이며 CPU 제한 사항이 아니므로 스레딩이 도움이되지 않을 가능성이 큽니다. –

    +0

    아이디어를 주셔서 감사하지만 위의 CodyC에 동의해야합니다. 파일을 x 줄 세그먼트로 분할하는 방법이 없다면 다른 스레드가 파일의 각 세그먼트를 처리하게할까요? 이것은 가능한가/실행 가능할 것인가? [각 라인이 완전한 레코드이고 불완전한 라인을 가짐으로써 데이터를 잃어 버릴 위험이 없습니다.] –