3

.dbf ファイルからデータを抽出し、それを xml に変換する必要があります。私はそれをうまくやるルーチンを書きました。ただし、現在、2GB 以上の非常に大きな .dbf ファイルが発生しています。そして、このコードはそれらのファイルに対して OutOfMemoryException をスローします。

Public Function GetData() As DataTable
    Dim dt As New DataTable(Name)
    Dim sqlcommand As String= "Select * From MyTable"
    Dim cn As New OleDbConnection(myconnectionstring)

    Try
        cn.Open()
        Dim cmd As New OleDbCommand(sqlcommand, cn)
        dt.Load(cmd.ExecuteReader())
    Catch ex As Exception
        Throw ex
    Finally
        dt.Dispose()
        cn.Close()
        cn.Dispose()
    End Try
    Return dt

問題は、同じ 2GB の .dbf ファイルに対してデバッグ モードで Visual Studio を使用して自分のコンピューターでこの同じコードを実行しても、例外はスローされないということです。Visual Studio がメモリを管理する方法と、アプリが単独で行う方法のようです。

とにかくメモリの問題を回避する方法はありますか? 同様の結果で DataAdapter を使用してみました。Visual Studio で見られるこの動作は、予期された仕様ですか?

4

4 に答える 4

6

データテーブルはメモリ内にあるため、大きなファイルでは失敗するか、ファイルのサイズによっては非常に遅くなります。

SqlDataReader を使用してレコードごとにデータを読み取り、XmlWriter を使用して XML ファイルを作成する必要があります。

このようなもの(コードはチェックされていません)

Public Sub WriteToXml(Dim xmlFileName As String, Dim connectionString)
    Dim writer As XmlWriter
    writer = XmlWriter.Create(xmlFileName)
    Dim commandText As String= "Select * From MyTable"
    Dim connection As New OleDbConnection(connectionString)

    Try
        connection.Open()
        Dim command As New OleDbCommand(commandText, connection)
        Dim reader As SqlDataReader
        reader = myCommand.ExecuteReader()

        While reader.Read()             
            write.WriteRaw("xml")
        End While
    Catch ex As Exception
        Throw ex
    Finally        
        connection.Close()
        connection.Dispose()
    End Try
End Sub
于 2009-09-24T20:10:49.807 に答える
4

2GB のデータベース全体をメモリにロードすることはできません。データベース レコードをチャンクでロードして処理する必要があります。

データベースの部分的なロードを行うには、たとえば、SELECT コマンドで TOP 句と ROWNUM 句を使用できます。詳細については、SQL Server のドキュメントを参照してください。

于 2009-09-24T20:00:14.467 に答える
1

次のような簡単なことをしてみませんか。

using (var writer = CreateXmlWriter(fileName))
{
  while (reader.Read()) 
  {
    var value = new ObjectFromDatabaseReader(reader);
    value.WriteXml(writer);
  }
}

これにより、一度に1行ずつデータがストリーミングされ、オブジェクトに変換されてからxmlとして保存されます。これはほとんどメモリを使用せず、非常に高速である必要があります。

于 2009-09-24T22:18:48.037 に答える
1

大きなファイルを処理したい場合は、DataSet を埋めずに DataReader を検討してください。テーブル全体をメモリにロードするのではなく、行ごとにロードします。また、この方法の代わりに SqlDataAdapter.Fill() を使用し、Dispose することを忘れないでください。

Dim conn As New SqlConnection(connection)
Dim adapter As New SqlDataAdapter()
adapter.SelectCommand = new SqlCommand(query, conn)
adapter.Fill(dataset)
adapter.Dispose()
conn.Dispose()

.Dispose() を呼び出すときに呼び出されるため、接続のために .Close() を呼び出す必要はありません。

PS: Reader を閉じないでください。おそらくそれが理由です。はい、VS.NET は GC よりも速く閉じます。

于 2009-09-24T20:00:10.863 に答える