我有一个非常大的图形存储在一个单维数组(大约1.1 GB)中,我可以将其存储在我的机器的内存中,该机器运行Windows XP,内存为2GB,虚拟内存为2GB。我能够在内存中生成整个数据集,但是当我尝试使用BinaryFormatter
将其序列化到磁盘时,文件大小变为大约50MB,然后给我一个内存不足的异常。我用来编写代码的代码与我在所有较小的问题中使用的代码相同:
StateInformation[] diskReady = GenerateStateGraph();
BinaryFormatter bf = new BinaryFormatter();
using (Stream file = File.OpenWrite(@"C:\temp\states.dat"))
{
bf.Serialize(file, diskReady);
}
搜索算法非常轻量级,我可以在此图表上执行搜索,一旦内存中没有问题。
我真的有3个问题:
有更可靠的方法吗? 将大型数据集写入磁盘。一世 猜你可以定义大到什么时候 数据集的大小接近 可用内存量, 虽然我不确定如何准确 就是这样。
我应该转移到更多数据库 中心方法?
有人能指点我吗? 关于阅读部分的文献 来自磁盘文件的大数据集 C#?
答案 0 :(得分:1)
我对这类大量信息的体验是手动将其写入磁盘,而不是使用内置序列化。
这可能不是很实际,具体取决于您 StateInformation 类的复杂程度,但如果它非常简单,您可以使用BinaryReader和{手动编写/读取二进制数据{3}}而是。这些将允许您按照代码规定的预期预定顺序直接读取/写入大多数值类型。
此选项应该允许您快速读取/写入数据,但如果您希望稍后将信息添加到StateInformation中,或者要将其取出,因为您必须管理升级文件,这样做很麻烦
答案 1 :(得分:1)
自己编写条目。一个简单的解决方案就是:
StateInformation[] diskReady = GenerateStateGraph();
BinaryFormatter bf = new BinaryFormatter();
using (Stream file = File.OpenWrite(@"C:\temp\states.dat"))
{
foreach(StateInformation si in diskReady)
using(MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, diskReady);
byte[] ser = ms.ToArray();
int len = ser.Length;
file.WriteByte((byte) len & 0x000000FF);
file.WriteByte((byte) (len & 0x0000FF00) >> 8);
file.WriteByte((byte) (len & 0x00FF0000) >> 16);
file.WriteByte((byte) (len & 0x7F000000) >> 24);
file.Write(ser, 0, len);
}
}
一次只需要一个StateInformation对象的内存,并且反序列化你读取四个字节,构造长度,创建一个大小的缓冲区,填充它并反序列化。
如果您创建更专业的格式,上述所有内容都可以针对速度,内存使用和磁盘大小进行严格优化,但以上内容将说明原则。
答案 2 :(得分:0)
StateInformation中包含哪些内容?这是一堂课吗?结构
如果您只是担心易于使用的容器格式(可以轻松序列化到磁盘) - 创建一个类型化的DataSet,将信息存储到DataSet中,然后使用 WriteXml()方法DataSet将其持久保存到磁盘。然后,您可以创建空DataSet,然后使用 ReadXml()将内容加载回内存。
如果StateInformation位于具有值类型的结构中,则可以通过直接引用文件来查看MemoryMappedFile来存储/使用数组的内容,将其视为内存。这种方法比DataSet复杂得多,但它有自己的一套优势。