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