Delphi TStringList包装器实现动态压缩

时间:2010-07-13 13:04:07

标签: delphi compression zip on-the-fly tstringlist

我有一个用于在TStringList中存储许多字符串的应用程序。字符串将在很大程度上彼此相似,并且我发现可以在运行中压缩它们 - 即,根据唯一文本片段的混合物以及对先前存储的片段的引用来存储给定字符串。诸如完全限定路径和文件名列表之类的StringLists应该能够被大大压缩。

有没有人知道实现这一点的TStringlist后代 - 即提供对未压缩字符串的读写访问权限,但是将它们存储在内部压缩,以便TStringList.SaveToFile生成压缩文件?

虽然您可以通过在每次访问之前解压缩整个字符串列表并在之后重新压缩它来实现这一点,但这会非常慢。我正在追求一些对增量操作有效的东西以及随机的“寻找”和读取。

TIA 罗斯

4 个答案:

答案 0 :(得分:2)

我认为没有任何可自由实现的实现(不是我知道的,尽管我已经在商业代码中编写了至少3个类似的结构),所以你必须自己动手。< / p>

Marcelo关于按顺序添加项目的说法非常相关,因为我认为您可能希望在添加时压缩数据 - 快速访问已经类似于添加项的条目,可以提供更好的性能而不是必须在整个集合中查找“最佳拟合条目”(相似性压缩所需)。

你可能想要阅读的另一件事是'绳索' - 概念上不同于字符串的类型,I already suggested to Marco Cantu一段时间之后。以每个'twine'的下一个指针为代价(缺少更好的单词),您可以连接字符串的各个部分而不保留任何重复数据。主要问题是如何检索可以组合成新“绳索”的零件,代表原始字符串。一旦问题得到解决,您可以随时将数据重建为字符串,同时仍然具有紧凑的存储空间。

如果你不想走“绳索”路线,你也可以尝试一种叫做“前缀减少”的东西,这是一种简单的压缩形式 - 只需用一个前一个字符串的索引开始每个字符串。应被视为新字符串前缀的字符数。请注意,您应该将其推回太远,否则访问速度将受到很大影响。在一个简单的实现中,我在索引上做了mod 16,以建立前缀减少开始的条目,这使我平均节省了大约40%的内存(当然这个数字完全取决于数据)。

答案 1 :(得分:0)

您可以尝试在Judy arrays周围包装Delphi或COM API。 JudySL类型可以解决这个问题,而且界面相当简单。

编辑:我假设您正在存储唯一的字符串,并希望(或乐意)按字典顺序存储它们。如果这些约束不可接受,那么Judy数组不适合你。请注意,如果您不对字符串进行排序,任何压缩系统都会受到影响。

答案 2 :(得分:0)

我想你希望从列表中获得一般的灵活性(包括删除操作),在这种情况下我不知道任何开箱即用的解决方案,但我建议采用以下两种方法之一:

  • 您将字符串拆分为单词和 保持分离成长的字典 在内部引用单词并保存索引列表

  • 您实现了与之相关的内容 zlib流在Delphi中可用,但是由块操作 例如可以包含10-100 字符串。在这种情况下,你仍然有 重新压缩/压缩完整的 阻止,但你支付的“价格”较低。

答案 3 :(得分:0)

我不认为你真的想在内存中压缩TStrings项目,因为它非常无效。我建议你看一下Zlib单元中的TStream实现。只需将常规流包装到加载时的TDecompressionStream和保存时的TCompressionStream(你甚至可以在那里发出gzip头)。 提示:您将要覆盖LoadFromStream / SaveToStream而不是LoadFromFile / SaveToFile