阵列等的磁盘存储

Posted

技术标签:

【中文标题】阵列等的磁盘存储【英文标题】:disk storage of arrays etc 【发布时间】:2011-05-05 08:56:57 【问题描述】:

有人有在磁盘上存储数据的经验吗?我拥有的是一个可以进行计算等的内存建模应用程序。基本上,数据存储为对象列表,这些对象列表具有嵌套的键值集合,例如 Dictionary>。

现在我使用 SQL-Server 作为持久层,但我很少使用它的特性。所以我想我可以自己将数据写入/读取到磁盘,以减少依赖并简化安装。

所以我写了一个小程序,将每个数组以大致这种格式写入磁盘,其中“ObjId”、“Type”、“Valid”和“Count”这些词实际上不在文件中,它们是第一个, 2nd, 3rd 和 byte[] 中的第 4 个 int,然后是 对。 52 来自 4 * 4 + 3 * (4 + 8)。 (int 4 字节,double 8 字节)

Bytes: 52

ObjId: 123 
Valid: 234  
Type: double
Count: 3
    1 .23
    2 .34
    3 .45

在现实生活中没有缩进等,它们都是长流中的连续字节。

这很好,写一次。但是当我想在中间的某个地方写一个额外的值时,我必须重写整个东西。我也不能轻易更新单个值。

另一种方法是将每个对象写入一个单独的文件,这样我只需要重写它。但这似乎效率很低,因为我得到的文件是 1kb,但磁盘上有 4kB,所以我会在那里浪费空间。

那么我需要做什么才能逐步写入磁盘上的这个文件?我知道 SqlServer 在它写入数据的地方有“页面”,这是要走的路吗?

有没有准备好解决这类问题的库?也许一些虚拟文件可以让我将它们视为单独的 byte[] 但将存储作为单个 psysical 文件处理?理想的压缩..(推动它,但谁知道..我以前很惊讶:-)

提前致谢,

格特-简

【问题讨论】:

【参考方案1】:

如果您不想要 RDBMS 的开销,您可以使用像 Berkeley DB 这样的键值数据库。这里有一个 C# 接口:

Berkeley DB for .NET

您可以为每个数组设置一个条目,并在需要时重写它。数据库文件的其余部分将保持不变,因此比重写整个文件要快得多。

您可以在写出数组时重用已经实现的序列化逻辑。您只需为每个数组添加一个唯一键。

【讨论】:

您好,谢谢!我知道 BDB 是一个 mysql 引擎,但从未考虑过它。我会在周末研究它。有一种方法可以将我的 byte[] 放在那里并取回它,这几乎就是我想要的。我更喜欢带有源代码的纯 C#,但这应该是足够成熟的技术,可以用作黑匣子。【参考方案2】:

您将无法避免每个对象只有 1 个文件,或者在进行更改时必须重写整个对象列表。你可以使用SQLite。它是一个非常快速和高效的单文件嵌入式数据库。这意味着您的应用程序对 db 没有任何外部依赖项。

如果您直接写入数据,您应该在binary format. 中读取和写入您的整数,而不是它们的 ASCII 表示形式(1234 = 4 字节,但是是 1 字节 int)。

这将加快文件的读写速度。

文章中的一些代码:

    Hashtable addresses = new Hashtable();
    addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052");
    addresses.Add("Fred", "987 Pine Road, Phila., PA 19116");
    addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301");

    // To serialize the hashtable and its key/value pairs,  
    // you must first open a stream for writing. 
    // In this case, use a file stream.
    FileStream fs = new FileStream("DataFile.dat", FileMode.Create);

    // Construct a BinaryFormatter and use it to serialize the data to the stream.
    BinaryFormatter formatter = new BinaryFormatter();
    try 
    
        formatter.Serialize(fs, addresses);
    
    catch (SerializationException e) 
    
        Console.WriteLine("Failed to serialize. Reason: " + e.Message);
        throw;
    

【讨论】:

对 BinaryFormatter 的一个小警告是,所生成的文件对于应用程序的程序集或 .NET Framework 都不是版本容错的。 @High Performance Mark - 是的,你是对的,我应该放 255 之类的。 嗨,我以前使用过 BinaryFormatter,但它在我不需要的实际数据之间注入了相当多的关于类等的元数据,并且使文件相当膨胀。此外,它对类的更改处理得相当差,所以我没有考虑它。谢谢,GJ【参考方案3】:

在磁盘上存储信息的方法有一千零一种。您已经对数据库提出了建议。您可能还需要考虑结构化文件格式,例如 HDF5,它具有包括 C# 在内的语言的绑定。 HDF5 的优势之一是它支持存储 n 维数组。

【讨论】:

【参考方案4】:

除了这里提出的其他建议之外,您还可以尝试使用带有 NORM 的 MongoDB,它是一种出色的、无摩擦(无需配置数据库、无需创建对象关系映射)的方式来存储数据,而无需 SQL 服务器的开销/成本。

【讨论】:

以上是关于阵列等的磁盘存储的主要内容,如果未能解决你的问题,请参考以下文章

存储磁盘阵列

光纤硬盘磁盘阵列sas硬盘磁盘阵列哪个好

磁盘阵列

光纤存储重组raid磁盘阵列和raid数据恢复成功案例

RAID磁盘阵列笔记

服务器 磁盘阵列讲解