首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何对.xz文件中的特定块进行随机访问?

如何对.xz文件中的特定块进行随机访问?
EN

Stack Overflow用户
提问于 2022-06-18 17:11:50
回答 2查看 130关注 0票数 1

我的目标是能够减少查看特定部分所需的时间,从非常大的日志文件压缩到.xz格式。

例如,如果.xz文件是6GB压缩文件和60 6GB未压缩文件,使用简单的命令(如xzcat <file> | tail -1 )来查看未压缩文件的最后一行,则需要等待许多分钟才能解压整个文件。

通过阅读https://stackoverflow.com/a/34053829/12132601,我的理解是.xz文件被组织成块,如果您能够找到要取的文件的正确起始位置和长度,就可以解压特定的块。然而,我无法理解这一点:

-您可以使用xz -详细-列表FILE.xz获得块偏移量列表。如果您想要最后一个块,您需要它的压缩大小(第5列)加上36个字节的开销(通过比较大小和hd big.log.sp0.xz |grep 7zXZ找到)。使用尾-c获取该块,并通过xz进行管道。由于上面的问题需要文件的最后一行,所以我将其通过尾-n1进行传输:

SIZE=$(xz -详细

特别是关于36的管理费用以及他是如何得到的。

加上36字节的开销(通过将大小与hd big.log.sp0.xz |grep 7zXZ进行比较找到)

我一直在读https://tukaani.org/xz/xz-file-format.txt,但是我看不懂。我不知道36是从哪里来的。

36肯定和我的档案不一样。实际上,我试过1到100次,但都没有效果。

我的文件的前3行与hd类似

代码语言:javascript
复制
00000000  fd 37 7a 58 5a 00 00 04  e6 d6 b4 46 04 c0 e2 c3  |.7zXZ......F....|
00000010  39 80 80 80 08 21 01 14  00 00 00 00 3e 0b 39 68  |9....!......>.9h|
00000020  e9 e2 3f f0 00 5d 00 18  8d 82 f9 18 7b b2 75 c6  |..?..]......{.u.|

xz -lvv <myxzfile>的前几行如下所示:

代码语言:javascript
复制
<myxzfile> (1/1)
  Streams:            1
  Blocks:             4,080
  Compressed size:    5,789.9 MiB (6,071,150,860 B)
  Uncompressed size:  63.7 GiB (68,443,750,160 B)
  Ratio:              0.089
  Check:              CRC64
  Stream padding:     0 B
  Streams:
    Stream    Blocks      CompOffset    UncompOffset        CompSize      UncompSize  Ratio  Check      Padding
         1     4,080               0               0   6,071,150,860  68,443,750,160  0.089  CRC64            0
  Blocks:
    Stream     Block      CompOffset    UncompOffset       TotalSize      UncompSize  Ratio  Check      CheckVal          Header  Flags        CompSize    MemUsage  Filters
         1         1              12               0         942,592      16,777,216  0.056  CRC64      e77988a5264b499e      20  cu            942,562       5 MiB  --lzma2=dict=4MiB
         1         2         942,604      16,777,216         887,748      16,777,216  0.053  CRC64      b1124241f57be325      20  cu            887,718       5 MiB  --lzma2=dict=4MiB
         1         3       1,830,352      33,554,432         836,008      16,777,216  0.050  CRC64      0b9ed8b7bd1be895      20  cu            835,978       5 MiB  --lzma2=dict=4MiB
         1         4       2,666,360      50,331,648         893,172      16,777,216  0.053  CRC64      4399327c125c6a13      20  cu            893,144       5 MiB  --lzma2=dict=4MiB
         1         5       3,559,532      67,108,864         757,964      16,777,216  0.045  CRC64      908e32d2276f5b4b      20  cu            757,933       5 MiB  --lzma2=dict=4MiB

如果我只想解压缩第三个块,我天真地认为head -c 2666360 2022-06-16T00:00:00.xz | tail -c 836008 | unxz -c会工作,但它当然不能。我应该采取的文件的起始位置和长度是什么,为什么?

EN

回答 2

Stack Overflow用户

发布于 2022-06-18 17:29:18

看起来,我只需要将前12个字节cat到我需要的块上。即

代码语言:javascript
复制
cat <(head -c 12 2022-06-16T00:00:00.xz) <(head -c 2666360 2022-06-16T00:00:00.xz | tail -c 836008) | unxz -c
票数 0
EN

Stack Overflow用户

发布于 2022-06-19 16:52:18

在解压缩文件时,默认情况下的unxz (或xz -d)命令尝试自动检测存档的类型(相当于--format=auto)。这适用于xz文件(但在开始时需要xz流头)。

但是,如果您剪切一个xz文件以只取一个块,它就不再是一个有效的xz文件了,因为它错过了xz流头(这是xz文件的前12个字节,假设xz文件只由一个流组成)、xz索引和xz流页脚。

但是,如果在xz文件上取前12个字节,然后追加一个块的字节,则仍然缺少xz索引和xz流页脚,解压缩文件的工具可能支持也可能不支持(*)。看来unxz命令支持得很好,所以这是一种方法!

(*)读取xz文件的主要方法有两种:

流模式中的

  1. :在xz块出现时解压缩它们(这就是xz正在做的事情),缺点是如果您拥有整个文件,就不能随机访问
  2. :从xz索引和xz流页脚获取有关块的信息,以及从好块

中读取数据。

另一种方法是进一步削减xz块的数据,只获取压缩的数据,然后用unxz -F raw解压缩它。然而,这有两个缺点:

  • 您需要进一步查看该块,以便能够知道需要将权限筛选器作为命令标志

传递给

  • 的字节数。

因此,我想说,这是不切实际的手工操作。

阅读

https://stackoverflow.com/a/34053829/12132601

在那篇文章中,他们不是在xz文件中有一个包含几个块的流,而是创建(然后读取)一个xz文件,该文件由几个流组成,每个流都有一个块。

在这种情况下,使用tail -c获取最后一个流就足够了,因为一个由一个流组成的文件是一个有效的xz文件。

我没有找到任何方法可以轻松地使用xz命令行在xz文件中进行随机访问(也没有找到pixz )。

如果您正在使用Python,那么我将借此机会突出显示我编写的python-xz库,作为lzma的插入替代,以便透明地执行对xz文件的随机访问。

在你的例子中,像这样的事情:

代码语言:javascript
复制
import xz

with xz.open('2022-06-16T00:00:00.xz') as f:
    f.seek(33_554_432)  # position is decompressed offset
    print(f.read(0x1000000))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72671207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档