delphitstringlist包装器实现动态压缩

delphitstringlist包装器实现动态压缩,delphi,compression,zip,on-the-fly,tstringlist,Delphi,Compression,Zip,On The Fly,Tstringlist,我有一个在TStringList中存储许多字符串的应用程序。这些字符串在很大程度上彼此相似,我想到可以动态压缩它们——即,以独特文本片段加上对先前存储片段的引用的混合方式存储给定字符串。StringList(如完全限定路径和文件名的列表)应该能够被大大压缩 是否有人知道实现此功能的TStringlist子代,即提供对未压缩字符串的读写访问,但将其存储在内部压缩,以便TStringlist.SaveToFile生成压缩文件 虽然您可以通过在每次访问之前解压缩整个stringlist并在访问之后重新

我有一个在TStringList中存储许多字符串的应用程序。这些字符串在很大程度上彼此相似,我想到可以动态压缩它们——即,以独特文本片段加上对先前存储片段的引用的混合方式存储给定字符串。StringList(如完全限定路径和文件名的列表)应该能够被大大压缩

是否有人知道实现此功能的TStringlist子代,即提供对未压缩字符串的读写访问,但将其存储在内部压缩,以便TStringlist.SaveToFile生成压缩文件

虽然您可以通过在每次访问之前解压缩整个stringlist并在访问之后重新压缩来实现这一点,但这样做的速度会非常慢。我想要的是一些对增量操作和随机“搜索”和读取有效的东西

短暂性脑缺血发作
Ross

您可以尝试包装一个Delphi或COM API。JudySL类型可以实现这一点,并且有一个相当简单的接口


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

我想您希望列表具有一般的灵活性(包括删除操作),在这种情况下,我不知道任何现成的解决方案,但我建议使用以下两种方法之一:

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

  • 您实现了与 zlib流在Delphi中可用,但由块操作 例如,可以包含10-100个 串。在这种情况下,您仍然有 要重新压缩/压缩完整的 块,但你支付的“价格”更低


我认为没有任何免费的实现(据我所知,尽管我已经在商业代码中编写了至少3个类似的结构),所以您必须自己动手

Marcelo关于按顺序添加项的评论非常相关,因为我认为您可能希望在添加时压缩数据-快速访问与所添加项相似的条目,比查找“最佳匹配条目”(相似性压缩所需)提供更好的性能全套的

另一件你可能想了解的事情是“ropes”——一种概念上与字符串不同的类型,而字符串在不久前就已经出现了。以每“twine”下一个指针为代价(因为没有更好的词),您可以连接字符串的各个部分,而无需保留任何重复数据。主要问题是如何检索可以组合成新的“rope”的部分,表示原始字符串。一旦这个问题得到解决,您就可以随时将数据重建为字符串,同时保持紧凑的存储


如果你不想走“绳索”路线,你也可以尝试一种叫做“前缀缩减”的方法,这是一种简单的压缩形式——只需在每个字符串开始时使用前一个字符串的索引和应作为新字符串前缀的字符数。请注意,您不应该在太远的时间重复此操作,否则访问速度将受到很大影响。在一个简单的实现中,我对索引执行了
mod 16
,以确定前缀缩减开始的条目,这平均为我节省了大约40%的内存(这个数字当然完全取决于数据)。

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

Judy不是一个“关联数组”吗?如果确实如此,它将取代TDictionary,而不是TStringList。我发现JudySL的唯一参考资料是:-这不是TStringList的替代品。哎哟COM中的跨语言包装器只是为了使用数据结构?不用了,谢谢。但是如果有人写了一个本地的Pascal/Delphi JudyArray,我肯定会试试。我其实不需要那么多灵活性。如果我正在检索(比如)10000000个文件和路径名的目录列表,并希望以压缩形式存储它们,那么您提到的第一种方法就可以了。我只是想知道是否有现成的解决方案。压缩数据仍然必须解压缩才能读取,因此本质上是低效的。如果您确实需要在内存中快速读取某些内容,请保留未压缩的键列表。