AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 429197
Accepted
bravokeyl
bravokeyl
Asked: 2018-03-10 01:41:49 +0800 CST2018-03-10 01:41:49 +0800 CST 2018-03-10 01:41:49 +0800 CST

使用偏移量读取部分下载的 gzip

  • 772

假设有一个巨大db.sql.gz的 100GB 可用https://example.com/db/backups/db.sql.gz并且服务器支持范围请求。

因此,我没有下载整个文件,而是下载了y带有字节偏移量(比如说 1000 字节)的x字节(比如说 1024 字节),如下所示。

curl -r 1000-2024 https://example.com/db/backups/db.sql.gz

使用上述命令,我能够下载 gzip 文件的部分内容,现在我的问题是如何读取该部分内容?

我试过gunzip -c db.sql.gz | dd ibs=1024 skip=0 count=1 > o.sql了,但这给出了一个错误

gzip:dbrange.sql.gz:不是 gzip 格式

该错误是可以接受的,因为我猜在文件的顶部可能有描述编码的标题块。


我注意到,如果我下载没有偏移量的文件,我可以使用gunzip和管道读取文件。

curl -r 0-2024 https://example.com/db/backups/db.sql.gz

gzip streams
  • 2 2 个回答
  • 3653 Views

2 个回答

  • Voted
  1. Best Answer
    Stephen Kitt
    2018-03-10T02:19:46+08:002018-03-10T02:19:46+08:00

    gzip不生成块压缩文件(有关血腥细节,请参阅RFC),因此它本身不适合随机访问。您可以从流中开始读取并随时停止,这就是您的curl -r 0-2024示例有效的原因,但您不能在中间选择流,除非您有一个补充文件来提供丢失的数据(例如索引文件由gztool) 创建。

    为了实现您想要做的事情,您需要使用某种块压缩;例如 bgzip(生成可以通过 plain 解压缩的文件gzip)或bzip2, 并在接收端做一些工作来确定块边界的位置。Peter Cock 写了一些关于这个主题的有趣帖子:BGZF - 被封锁、更大、更好的 GZIP!,随机访问BZIP2?

    • 4
  2. circulosmeos
    2019-09-16T11:39:06+08:002019-09-16T11:39:06+08:00

    只是FWIW,gzip可以随机访问,如果以前的索引文件已经创建......

    我开发了一个命令行工具,如果提供了索引,它可以快速(几乎)随机访问 gzip(如果没有提供,则会自动创建):

    https://github.com/circulosmeos/gztool

    gztool可用于访问原始 gzip 文件的块,如果这些块是在索引指向的特定字节点处检索到的(肯定是-1 字节,因为 gzip 是位流,而不是字节),或者更好,在他们之后。

    例如,如果索引点从gzip 文件的压缩字节1508611开始(gztool -ll index.gzi提供此数据),并且我们希望在此之后有 1M 压缩字节:

    $ curl -r 1508610-2508611 https://example.com/db/backups/db.sql.gz > chunk.gz
    
    • 请注意,chunk.gz在磁盘上只会占用块大小!
    • 另请注意,它不是有效的 gzip 文件,因为它不完整。
    • 还要考虑到我们已经从所需的索引点位置减去 1 个字节进行检索。

    现在还必须检索完整的索引(以前只创建一次:例如,gztool -i *.gz为所有已压缩的文件创建索引,或同时压缩和创建索引)。gztool -c *请注意,索引约为 gzip 大小的 0.3%(如果gztool压缩数据本身,则要小得多)。

    $ curl https://example.com/db/backups/db.sql.gzi -o chunk.gzi
    

    现在可以使用gztool完成提取。必须知道compressed-1508610 的相应未压缩字节(或传递该字节的字节),但索引可以用gztool -ll. 请参阅此处的示例。假设它是字节 9009009。或者我们想要的未压缩字节只是传递了包含在 chunk.gz 中的相应第一个索引点。让我们再次假设在这种情况下这个字节也是 9009009。

    $ gztool -n 1508610 -b 9009009 chunk.gz > extracted_chunk.sql
    

    gztoolchunk.gz文件结束时将停止提取数据。

    也许很棘手,但可以在不改变压缩方法或压缩文件的情况下运行。但是需要为它们创建索引。


    注意:另一种不使用参数进行提取的方法是用稀疏零-n填充 gzip 文件:对于示例来说,这是在第一个检索文件之前使用命令完成的,因此:ddcurlchunk.gz

    $ dd if=/dev/zero of=chunk.gz seek=1508609 bs=1 count=0
    $ curl -r 1508610-2508611 https://example.com/db/backups/db.sql.gz >> chunk.gz
    $ curl https://example.com/db/backups/db.sql.gzi -o chunk.gzi
    

    这样,文件的前 1508609 个字节为零,但它们不占用磁盘空间。没有seekindd命令,零都写入磁盘,这对 也有效gzip,但这样我们就不会占用磁盘上不必要的空间。那么,gztool 命令就不需要这个-n参数了。不需要归零的数据,因为索引存在,gztool将使用它跳转到未压缩的 9009009 字节位置之前的索引点,因此所有先前的数据都将被忽略:

    $ gztool -b 9009009 chunk.gz > extracted_chunk.sql
    
    • 3

相关问题

  • 为什么 gzip 不创建相同大小的文件?

  • 解压缩文件夹中的 *.Z 文件返回错误

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve