【问题标题】:How to speed up the extraction of a large tgz file with lots of small files? [closed]如何加快提取包含大量小文件的大型 tgz 文件? [关闭]
【发布时间】:2015-12-24 17:26:52
【问题描述】:

我有一个 tar 存档(17GB),其中包含许多小文件(所有文件

  1. 我要提取它吗?在我的笔记本电脑上使用 7-zip 表示需要 20 小时(我认为需要更多时间)
  2. 我可以在不提取文件的情况下读取/浏览文件的内容吗?如果是,那么如何?
  3. 还有其他选择吗?

它实际上是一个经过处理的维基百科数据集,我应该在其上执行一些自然语言处理。

平台 Windows/Linux 不是问题;只要能尽快完成工作,任何事情都可以。

【问题讨论】:

  • 所以它是一个.tgz 文件,其中包含许多.zip 文件?还是只是一个包含许多文本文件的.tgz 文件?
  • 带有许多文本文件的.tgz
  • 里面有多少个文件?这么小的文件要花这么多时间,听起来很奇怪……
  • @MatteoItalia 我不知道有多少?但是看看imgur.com/fOiSHLq
  • 我觉得我在这里做的事情完全错了

标签: linux windows archive large-data


【解决方案1】:

EDIT>这个答案背后的想法是即时处理存档的内容,从而避免在将存档内容写入磁盘时必然发生的任何昂贵(缓慢)的 IO。

不知道应该如何处理这些数据是很难回答的。

如果您的“自然语言处理”软件可以处理来自管道(流)的输入,那么您可以处理存档的内容,而无需使用以下任何变体进行提取:

tar -xf hugeFile.tar -O | yourSoftware

这会将这个存档中所有文件的组合内容通过管道传输到yourSoftware(在 linux 或 cygwin 下)。

例如要计算总字数,请使用以下方法:

tar -xf hugeFile.tar -O | wc -w

假设您可能需要测试您的算法,最好在一些较小的子集上进行测试,即前 10.000 行:

tar -xf hugeFile.tar -O | head -n10000 | yourSoftware

如果您的处理软件需要将文件保存在磁盘上,那么您需要解压缩此存档(请注意,某些文件系统不能很好地处理许多小文件 - 它可能会消耗比预期更多的可用空间和访问时间可能也很长)。

【讨论】:

  • 这需要多少时间,
  • 我不知道,取决于很多因素。数据不会存储到磁盘,因此它可能相当快。当然,这取决于您处理数据的方式...
  • $ zcat Stage1_Articles.tgz /n gzip: Stage1_Articles.tgz: not in gzip format 现在怎么办?
  • @Vulcan:这意味着它实际上不是 tgz。如果你这样做file Stage1_Articles.tgz,输出是什么?
  • $ file Stage1_Articles.tgz Stage1_Articles.tgz: POSIX tar archive (GNU)
【解决方案2】:

我想您有一台 Linux 笔记本电脑或台式机,您的 hugearchive.tgz 文件位于某个 本地 磁盘上(不是远程网络文件系统,这可能太慢了)。如果可能,将 hugearchive.tgz 文件放在一些快速磁盘(最好是 SSD,而不是磁旋转硬盘)和快速的 Linux 原生文件系统(Ext4、XFS、BTRFS,而不是 FAT32 或 NTFS)上。

请注意,.tgz 文件是 .tar 文件的 gnu 压缩压缩文件。

下次你得到一个巨大的存档时,考虑以afio存档格式询问它,这具有单独压缩不太小的文件的巨大优势(或者可能要求一些SQL转储 - 例如PostGreSQLSqliteMariaDB - 压缩形式)。

首先,您应该列出hugearchive.tgz gziped tar 存档中的文件名,并询问总字节数:

 tar -tzv --totals -f hugearchive.tgz > /tmp/hugearchive-list.txt

该命令将运行gunzip 以将.tgz 文件解压缩到某个管道(因此不会占用大量磁盘空间)并将目录写入/tmp/hugearchive-list.txt,然后您将继续你的 stderr 类似

  Total bytes read: 340048000 (331MiB, 169MiB/s)

当然这些数字是虚构的,你会得到更大的数字。但是您会知道档案的总累积大小是多少,并且您会知道它的目录。使用wc -l /tmp/hugearchive-list.txt 获取该目录中的行数,即存档中的文件数,除非某些文件被奇怪和恶意命名(例如,文件名中有一些换行符,这可能但很奇怪)。

我的猜测是您将在不到一小时的时间内处理您的庞大档案。详细信息取决于计算机,尤其是硬件(如果您负担得起,请使用一些 SSD,并获得至少 8GB 的​​ RAM)。

然后您可以决定是否能够提取所有文件,因为您知道它们需要多少总大小。由于您在/tmp/hugearchive-list.txt 中拥有目录,因此您可以在需要时轻松提取有用的文件。


为了它的价值,在我的 i3770K 台式机上,配备 16Gb RAM 和 SSD 和磁盘存储,我制作(用于试验)一个无用的巨大存档(专门为回答这个问题而制作,因为 我不'没有你的hugearchive.tgz 文件 ....) 和

sudo time tar czf /tmp/hugefile.tgz /bin /usr/bin /usr/local/bin /var 

并且花费了这段时间来创建该存档(所有这些文件系统都在 SSD 上):

 719.63s user 60.44s system 102% cpu 12:40.87 total

生成的/tmp/hugefile.tgz 有5.4 GB(注意它可能位于page cache 中)。

然后我尝试了:

time tar -tzv --totals -f /tmp/hugefile.tgz > /tmp/hugefile-list.txt

得到:

Total bytes read: 116505825280 (109GiB, 277MiB/s)
tar -tzv --totals -f /tmp/hugefile.tgz > /tmp/hugefile-list.txt
    395.77s user 26.06s system 104% cpu 6:42.43 total

生成的/tmp/hugefile-list.txt 有 2.3Mbytes(对于 23K 文件),没什么大不了的。

如果您的 tar 存档不是 GNU zipped,请不要在您的 tar 命令中使用 z

阅读 tar(1) 的文档(如果您使用它,还阅读 time(1) 的文档,更一般地阅读您正在使用的每个命令!)当然也使用命令行(不是一些GUI界面),还有learn一些shell脚本

顺便说一句,您以后可以隔离非常小的文件(小于 64 KB),例如将它们放入某个数据库(可能是一些 SqliteRedisPostGreSQLMongoDB 数据库,填充例如一个小脚本)或者一些 GDBM 索引文件。请注意,大多数文件系统在处理大量小文件时都会产生一些显着的开销。

学习 shell 脚本和一些脚本语言(Python、Lua、Guile、Ocaml、Common Lisp)和基本的数据库技术不是浪费时间。如果例如您正在开始攻读博士学位,这几乎是必需的技能。

我不知道也不使用(也不喜欢)Windows,所以我显然有偏见(我的第一个 Linux 是一些 Slackware,大约在 1993 年或 1994 年初使用 0.99.12 内核),但我强烈建议你在 Linux 上完成所有 NLP 工作(并让 Windows 仅用于玩视频游戏,当你有时间的时候),因为在 Linux 上编写脚本和组合许多有用的现有 free software 要容易得多。

【讨论】:

  • 我特别喜欢 BTW 之后的段落:)
  • sudo time tar czf /tmp/hugefile.tgz /bin /usr/bin /usr/local/bin /var 我尽力了,但无法弄清楚这些额外的路径指定了什么/bin /usr/bin /usr/local/bin /var
  • 是的,我的 Windows 仅用于玩游戏.. 与 lubuntu 的双启动可用于其他一切.. 而且我没有攻读博士学位。这是一个大学项目:P
  • 不要重复那个确切的命令!!!这只是创建一个大的 .tgz 存档的一个例子。我在 my上没有你的 hugefile.tgz > 机器,所以我为你创建了一个愚蠢的例子......
  • 您绝对需要 RTFM。不点链接就看不懂我的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 2018-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
相关资源
最近更新 更多