【问题标题】:Loading specific section of a compressed file stream加载压缩文件流的特定部分
【发布时间】:2010-05-07 10:00:54
【问题描述】:

我们有一个简单的二进制文件格式用于在我们的应用程序(C# .NET Windows 应用程序)中缓存数据。该格式基本上是一个简短的指示对象类型,后跟对象 id 的 guid(字符串),然后是任何对象特定数据(字符串 int 等等)。我们希望能够在同一个文件中存储许多对象(> 10000),但在某些情况下只能按需加载。我们的解决方案是在文件中保留对象位置的索引 - 所以当我们开始编写新对象时,我们会在文件流中记录对象开始的位置。当我们要加载这个对象时,我们使用这个索引位置来加载相关数据。这很好用。

但是,如果我们要压缩文件,这种方法仍然可行吗?我对压缩是如何工作的,特别是我们计划使用的 GZipStream 类 (System.IO.Compression) 不太感兴趣。据我了解,此类不支持 Seeking 或 Position 属性。是否仍然可以使用底层 FileStream 的 Seek 和 Position(我猜不是)?基本上,是否有可能有一个我们可以选择性加载的压缩文件,如果可以,我们该怎么做?

谢谢,

史蒂夫

【问题讨论】:

    标签: c# .net file compression gzipstream


    【解决方案1】:

    不,如果您想访问未压缩数据中的特定位置,则必须至少暂时解压缩它

    【讨论】:

      【解决方案2】:

      这不是真正的 Seek,但解决方案是:

      • 跟踪您在文件中的位置(最好通过实现从 BinaryReader 继承的“myBinaryReader”来完成)
      • 如果您正在寻找从当前位置向前的位置 - ReadBytes 直到您到达那里。
      • 如果您正在寻找当前位置之前的位置 - 重新打开文件以进行解压缩读取(这会将您的当前位置重置为零),然后 ReadBytes 直到您到达您想要的位置。

      显然,这根本不是一个理想的解决方案,但它仍然可以提供可接受的性能。 在我的情况下,压缩文件很容易放入内存中(未压缩不适合),所以我已将压缩文件加载到内存中。

      理想情况下,底层的 deflate 类将被更改以支持真正的 Seeks。

      【讨论】:

        【解决方案3】:

        更好的解决方案:

        使用 GZipStream 在内存中创建压缩字节,然后编写自己的类来控制缓存并将其写入磁盘(不要使用 DeflateStream)。还要编写你自己的类来从磁盘读取这些数据。

        然后您可以确保底层磁盘流支持 Seeks。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-23
          • 1970-01-01
          • 2018-09-19
          • 2011-07-21
          • 1970-01-01
          • 2017-04-17
          • 1970-01-01
          相关资源
          最近更新 更多