2

サイズが5mbから1gb+の範囲のスペース区切りのログファイルを読み取り、ファイルに含まれる情報に基づいてレポートを印刷するときに後で使用できるように、この情報をMySQLデータベースに保存するアプリケーションで忙しいです。私が試した/見つけた方法はうまくいきますが、非常に遅いです。

私は何か間違ったことをしていますか?または、非常に大きなテキストファイルを処理するためのより良い方法はありますか?

次のように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

これは機能しますが、大きなファイルの場合は非常に遅くなります。

次に、事前にディレクトリに書き込んだschema.iniファイルと組み合わせて、次の関数に従ってテキストファイルへのOleDB接続を使用してみました。

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ファイル:

[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

誰かがこれらのファイルをより速く読む方法について何か考えがありますか?

-編集-上記のコードのタイプミスを修正しました

4

2 に答える 2

2

そこには2つの潜在的に遅い操作があります:

  • ファイルの読み取り
  • データベースに大量のデータを挿入する

それらを分離し、最も時間がかかるテストを行います。つまり、ファイルを読み取るだけのテストプログラムと、大量のレコードを挿入するだけのテストプログラムを作成します。どれが最も遅いかを確認してください。

1つの問題は、ファイル全体をメモリに読み込んでいることである可能性がありますか?

ストリームで1行ずつ読んでみてください。これは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
于 2011-11-24T08:58:52.890 に答える
-2

私の頭の上のIDから、ワークロードを分散させるために、ある種のスレッドを実装してみてくださいと言います。

于 2011-11-23T14:10:12.117 に答える