.Net System.OutOfMemoryException填充数据表

.Net System.OutOfMemoryException填充数据表,.net,vb.net,dataset,oledb,dbf,.net,Vb.net,Dataset,Oledb,Dbf,我需要从.dbf文件中提取数据并将其转换为xml。我写了一个很好的例程。但是现在我们遇到了非常大的.dbf文件,比如2GB+。这段代码在这些文件上抛出OutOfMemoryException Public Function GetData() As DataTable Dim dt As New DataTable(Name) Dim sqlcommand As String= "Select * From MyTable" Dim cn As New OleDbConn

我需要从.dbf文件中提取数据并将其转换为xml。我写了一个很好的例程。但是现在我们遇到了非常大的.dbf文件,比如2GB+。这段代码在这些文件上抛出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
问题是-如果我在调试模式下通过VisualStudio在我的计算机上针对相同的2GB.dbf文件运行相同的代码,则不会引发异常。这几乎就像VisualStudio管理内存的方式与应用程序单独管理内存的方式不同


有没有办法解决内存问题?我尝试过使用DataAdapter,结果类似。我在Visual Studio中看到的这种行为是预期的吗?

如果要处理大文件,请考虑不填充数据集的DataReader;它不会在内存中加载整个表,而是逐行加载。并使用SqlDataAdapter.Fill()代替这种方式,不要忘记处理它

Dim conn As New SqlConnection(connection)
Dim adapter As New SqlDataAdapter()
adapter.SelectCommand = new SqlCommand(query, conn)
adapter.Fill(dataset)
adapter.Dispose()
conn.Dispose()
您实际上不需要为连接调用.Close(),因为它是在您调用.Dispose()时调用的


附言:你们不关闭阅读器,这可能就是原因。是的,VS.NET将比GC更快地关闭它。

您无法在内存中加载整个2GB数据库。您需要分块加载和处理数据库记录


要部分加载数据库,可以在SELECT命令中使用TOP和ROWNUM子句。有关详细信息,请参阅SQL Server文档。

内存中有一个数据表,因此它在处理大文件时会失败,或者速度会非常慢,具体取决于文件的大小

您需要使用SqlDataReader逐个记录地读取数据记录,并使用XmlWriter创建XML文件

类似这样的内容(代码未选中)


为什么不做一些简单的事情,比如:

using (var writer = CreateXmlWriter(fileName))
{
  while (reader.Read()) 
  {
    var value = new ObjectFromDatabaseReader(reader);
    value.WriteXml(writer);
  }
}
这只需一次将数据流化为一行,转换为一个对象,然后另存为xml。这几乎不会使用任何内存,应该非常快

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