C#数据表(DataRowCollection)存储在临时文件中,而不是内存中?

C#数据表(DataRowCollection)存储在临时文件中,而不是内存中?,c#,memory,datatable,temporary-files,C#,Memory,Datatable,Temporary Files,我想用实现DataRowCollection的自定义类替换DataTable,方法是将行存储在临时数据文件中,而不是将它们保存在内存中 我知道这比内存中的表慢,但我偶尔需要处理那些根本不适合ram(大于4GB的数据)的表。在运行结束时,我将放弃该表并删除临时文件 表数据来自数据库查询。我知道我可以更改查询以减小返回的数据集的大小。这不是重点。关键是内存总是会有一些限制,我希望可以选择使用一个慢的临时文件,而不是仅仅说“你不能那样做” 是否有预先编写的类或方法来完成此操作?看来我正在重新发明轮子

我想用实现DataRowCollection的自定义类替换DataTable,方法是将行存储在临时数据文件中,而不是将它们保存在内存中

我知道这比内存中的表慢,但我偶尔需要处理那些根本不适合ram(大于4GB的数据)的表。在运行结束时,我将放弃该表并删除临时文件

表数据来自数据库查询。我知道我可以更改查询以减小返回的数据集的大小。这不是重点。关键是内存总是会有一些限制,我希望可以选择使用一个慢的临时文件,而不是仅仅说“你不能那样做”

是否有预先编写的类或方法来完成此操作?看来我正在重新发明轮子

以下是我的骨骼起点:

/// <summary>
/// like DataTable, but storing data in a file instead of memory
/// </summary>
public class FileBackedDataTable : DataTable, IIntegrationTest
{
    new public FileBackedDataRowCollection Rows = null;

    // Summary:
    //     Initializes a new instance of the System.Data.DataTable class with no arguments.
    public FileBackedDataTable()
    {
        Rows = new FileBackedDataRowCollection(this);
    }
}

/// <summary>
/// like a DataRowCollection but data is stored in a file, not in memory
/// </summary>
public class FileBackedDataRowCollection : ICollection, IEnumerable, IDisposable
{
    /// <summary>
    /// internally track each file record
    /// </summary>
    class recordInfo
    {
        public long recordPosition;
        public int recordLength;
        public int recordMaxLength;
        public long hash;
    }

    DataTable table;

    ArrayList rows = new ArrayList();

    public FileBackedDataRowCollection(DataTable table)
    {
        this.table = table;
        openBackingFile(table);
    }

    public int Count 
    { 
        get { return rows.Count; } 
    }

    public void Clear()
    {
        rows.Clear();
        truncateBackingFile();
    }

    public DataRow this[int index]
    {
        get
        {
            recordInfo info = (recordInfo)rows[index];
            return readRow(info);
        }
        set
        {
            writeRow(index, value);
        }
    }

    private void writeRow(int index, DataRow value)
    {
        byte[] bytes = rowToBytes(value);
        recordInfo info = (recordInfo)rows[index];
        if (bytes.Length <= info.recordMaxLength)
        {
            info.recordLength = bytes.Length;
            info.hash = value.GetHashCode();
            writeBytes(info.recordPosition, bytes);
        }
        else
        {
            rows[index] = appendRow(bytes, value.GetHashCode());
        }
    }

    private DataRow readRow(recordInfo recordInfo)
    {
        byte[] bytes = readBytes(recordInfo.recordPosition, recordInfo.recordLength);
        DataRow row = bytesToRow(bytes);
        return row;
    }

    public void Add(DataRow r)
    {
        byte[] bytes = rowToBytes(r);
        recordInfo info = appendRow(bytes, r.GetHashCode());
        rows.Add(info);
    }

    private recordInfo appendRow(byte[] bytes, long hash)
    {
        recordInfo info = new recordInfo();
        info.recordLength = bytes.Length;
        info.recordMaxLength = info.recordLength;
        info.recordPosition = appendBytes(bytes);
        info.hash = hash;
        return info;
    }
//
///与DataTable类似,但将数据存储在文件而不是内存中
/// 
公共类FileBackedDataTable:DataTable,IIintegrationTest
{
新的公共FileBackedDataRowCollection行=null;
//总结:
//初始化System.Data.DataTable类的新实例,不带任何参数。
公共FileBackedDataTable()
{
行=新FileBackedDataRowCollection(此);
}
}
/// 
///与DataRowCollection类似,但数据存储在文件中,而不是内存中
/// 
公共类FileBackedDataRowCollection:ICollection、IEnumerable、IDisposable
{
/// 
///内部跟踪每个文件记录
/// 
类记录信息
{
公共长期职位;
公共长度;
公共整数记录最大长度;
公共长散列;
}
数据表;
ArrayList行=新的ArrayList();
公共FileBackedDataRowCollection(数据表)
{
this.table=表格;
openBackingFile(表);
}
公共整数计数
{ 
获取{return rows.Count;}
}
公共空间清除()
{
行。清除();
truncatebackfile();
}
公共数据行此[int索引]
{
得到
{
recordInfo=(recordInfo)行[索引];
返回readRow(信息);
}
设置
{
writeRow(索引、值);
}
}
私有void writeRow(整数索引,数据行值)
{
字节[]字节=行字节(值);
recordInfo=(recordInfo)行[索引];

如果(bytes.Length您可以使用。但是我会支持其他人,最好首先限制您从数据库中获取的记录。

最近,我一直在查看System.Data.SQLite以保存一些应用程序数据,而不是自己编写一个


使用SQLite创建一个临时文件,并在那里加载您的旧数据,怎么样?然后您可以像本地文件一样使用它,并在咀嚼后删除。

几乎100%您的计划是糟糕的设计。请花一些时间重新设计,使用您的同事数据库,而不是为了处理大块数据而创建的文件。如果需要,您可以编写存储过程如果数据库允许,则使用C#或其他语言


描述一下你想如何操作数据,你就会得到真正问题的真正答案。它要么需要SQL查询,要么如果不能用SQL查询,几乎可以肯定地用较小的数据量在某种循环中完成。

我不知道你在做什么,但我真的认为
分页
是解决问题的方法您的问题是否正在对数据库中的DataTable执行某些操作?也可以在数据库中查询特定范围的行,这样您就不需要将整个表保存在内存中。您需要一次处理一行,还是它们相互影响?如果您可以单独处理每一行,请使用DataReader来一次只对每一行进行一次et-非常快,占用的内存非常少。对我来说,这似乎是个坏主意。我非常确定可以在DBMS端进行处理…确定不会向用户显示>4Gb的表。:)撇开这一点不谈,你正在考虑使用内存映射文件吗?这可能会加快缓存数据表的速度……我很难看出这样做的好处。我很感激有时候RAM很难找到,特别是当你有非常大的表要查询时。我是不是遗漏了什么?谢谢,但这不会有帮助,因为它假定ataTable已经可以在ram中使用了。对……你可以部分加载然后保存。另外,硬盘上有虚拟内存。这里有一个链接,指向编写原始SQLite的人的视频。之所以接受,是因为我的问题的正确答案确实是“做不到”。多年来,我经常后悔回答“是”很好,我认为如果你采取这种方法,完全放弃你的想法,你的解决方案就不会像最初的计划那样尽快成为“遗留问题”!