C# DataTable(DataRowCollection) 存放在临时文件中,不是内存?

标签 c# memory datatable temporary-files

我想用实现 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;
    }

最佳答案

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

如何使用 SQLite 创建一个临时文件并在其中加载旧数据?然后你可以像本地文件一样使用它,并在咀嚼后删除。

关于C# DataTable(DataRowCollection) 存放在临时文件中,不是内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6064850/

相关文章:

c# - Context.GetExternalFilesDir() 不接受 null

c# - 如何更改 ASP.Net MVC 5 中的默认 "[field value] already taken"错误消息?

javascript - jQuery DataTable 多行表头

jquery - 在引导数据表中分页后未触发行单击事件

C# 并行 - 重复迭代

c# - 在 XPath 中查找带有空格的类

android - 用于检查 android 中的内存泄漏的工具

c++ - 使用 nullptr 计算指针偏移是否安全?

Java 应用程序存在大量内存问题

c# - 将按钮列添加到数据表