代码之家  ›  专栏  ›  技术社区  ›  Pavel Radzivilovsky

用于随机访问压缩数据文件的简单API

  •  5
  • Pavel Radzivilovsky  · 技术社区  · 14 年前

    请推荐适合以下任务的技术。

    我有一个相当大(500MB)的数据块,基本上是一个数字矩阵。数据熵很低(应该可以很好地压缩),存储成本也很高。

    我要找的是,用一个好的压缩算法(比如说GZip)对其进行压缩,该算法带有标记,可以偶尔进行随机访问。随机访问,如“从原始(未压缩)流中的位置[64位地址]读取字节”。这与经典的平减指数库(如ZLIB)略有不同,ZLIB可以让您连续解压缩流。我想要的是,在延迟时随机访问,比如说,每读取一个字节就有1MB的解压工作。

    当然,我希望使用现有的图书馆,而不是重新发明NIH的轮子。

    8 回复  |  直到 14 年前
        1
  •  2
  •   jkff    14 年前

    如果您使用Java,我刚刚发布了一个库: http://code.google.com/p/jzran .

        2
  •  1
  •   Marcus Adams    14 年前

    Byte Pair Encoding 允许随机访问数据。

    使用它不会获得很好的压缩效果,但是为了获得一棵树,你牺牲了自适应(可变)哈希树,所以你可以访问它。

    然而,您仍然需要某种索引才能找到特定的“字节”。既然您可以接受1MB的延迟,那么您将为每1MB创建一个索引。希望您能找到一种方法,使索引足够小,仍然可以从压缩中受益。

    这种方法的好处之一就是随机访问编辑。可以在相对较小的数据块中更新、删除和插入数据。

    如果很少访问,可以使用gzip压缩索引,并在需要时对其进行解码。

        3
  •  1
  •   Jerry Coffin    14 年前

    如果你想最小化所涉及的工作,我只需要将数据分成1MB(或其他)块,然后将这些块放入PKZIP存档。然后需要一小段前端代码来获取文件偏移量,然后除以1M以获得要解压缩的正确文件(显然,使用剩余部分来获得该文件中的正确偏移量)。

    编辑:是的,现有的代码可以处理这个问题。InfoZip解压的最新版本(最新版本为6.0)包括 api.c .除此之外,这包括 UzpUnzipToMemory --您向它传递一个ZIP文件的名称,以及要检索的归档文件中的一个文件的名称。然后得到一个保存该文件内容的缓冲区。要更新,您需要 应用程序编程接口。C 来自zip3。0,使用 ZpInit ZpArchive (尽管它们不像解压端那么简单)。

    或者,您可以在后台运行一个zip/unzip副本来完成这项工作。这并没有那么简洁,但毫无疑问,实现起来要简单一些(如果你愿意的话,还可以让你很容易地切换格式)。

        4
  •  1
  •   hoxnox    10 年前

    看看我的项目- csio 我想这正是你想要的:像stdio一样的接口和多线程压缩程序。

    它是用C语言编写的库,提供CFILE结构和函数 cfopen , cfseek , cftello ,等等。您可以将其用于常规(未压缩)文件和在dzip实用程序帮助下压缩的文件。本实用工具包含在项目中,并用C++编写。它生成有效的gzip存档,可以由标准实用程序以及csio处理。dzip可以压缩多个线程(参见 -j 选项),因此它可以非常快速地压缩非常大的文件。

    典型用法:

    dzip -j4 myfile
    
    ...
    
    CFILE file = cfopen("myfile.dz", "r");
    off_t some_offset = 673820;
    cfseek(file, some_offset);
    char buf[100];
    cfread(buf, 100, 1, file);
    cfclose(file);
    

    它是麻省理工学院许可的,所以你可以在你的项目中不受限制地使用它。有关更多信息,请访问github上的项目页面: https://github.com/hoxnox/csio

        5
  •  0
  •   Edward Strange    14 年前

    压缩算法通常是分块工作的,我想你可以根据块的大小来设计一些东西。

        6
  •  0
  •   Elpezmuerto    14 年前

    我建议使用 Boost Iostreams Library 促进Iostreams可用于创建访问TCP连接的流,或作为加密和数据压缩的框架。该库包括用于访问内存映射文件、使用操作系统文件描述符访问文件、代码转换、正则表达式文本过滤、行尾转换以及zlib、gzip和bzip2格式的压缩和解压缩的组件。

    升压库已被C++标准委员会接受为Tr2的一部分,因此它最终将被编译成大多数编译器( under std::tr2::sys )。它还具有跨平台兼容性。

    Boost Releases

    Boost Getting Started Guide 注意:只有部分 boost::iostreams 是只需要标题的库,链接时不需要单独编译库二进制文件或特殊处理。

        7
  •  0
  •   Gustavo V    14 年前
    1. 首先对大文件进行排序
    2. 把它分成你想要的大小(1MB)的块,并在名称中按顺序排列(文件01,文件02,…,文件NN)
    3. 从每个区块中获取第一个ID加上文件名,并将这两个数据放入另一个文件中
    4. 压缩块
    5. 您将能够使用您希望的方法对ID的文件进行搜索,可能是二进制搜索,并根据需要打开每个文件。

    如果需要深度索引,可以使用BTree算法,其中“页面”是文件。 在web上有几个这样的实现,因为它们的代码并不复杂。

        8
  •  0
  •   hippietrail    14 年前

    您可以使用bzip2,并基于James Taylor的API轻松创建自己的API seek-bzip2