【问题标题】: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 文件处理?理想的压缩..(推动它,但谁知道..我以前很惊讶:-)

提前致谢,

格特-简

【问题讨论】:

    标签: c# file multidimensional-array disk


    【解决方案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 服务器的开销/成本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-23
        • 1970-01-01
        • 1970-01-01
        • 2017-06-01
        • 2012-05-13
        相关资源
        最近更新 更多