该问题源自 Stack Overflow 上的一个 Crypto++ 库问题:如果使用 Gzip 类压缩,如何将文件名添加到存档中?。
Gzip,具体规定如下RFC 1952有一个用于原始文件名的可选字段:
(if FLG.FNAME set)
+=========================================+
|...original file name, zero-terminated...| (more-->)
+=========================================+
如果FNAME
在标志字段中设置了该位,则存在原始文件名。
我们将该功能添加到 Crypto++ 并在 OS X 上进行了测试。在 OS X 上,似乎程序gzip
、Unarchiver(默认存档程序)和档案浏览器(App Store 购买)不遵循原始文件名。也就是说,每个解压后的文件名都是存档名称(不含扩展名)gz
;而不是标头中显示的原始文件名。
例如,这是档案浏览器。原始文件名字段设置为test-filename.txt
,但该工具将文件名显示为gzip-test
,并将其解压为名为 的文件gzip-test
:
GZip
(并且Gunzip
是不是IEEE 标准Unix 命令,所以我真的不知道在哪里可以找到有关预期行为的知识。
这是预期的行为吗?还是我在三个不同的程序中都看到了错误?
如果这是预期的,那么原始文件名有什么实际用途?
答案1
根据gzip 手册页,使用时使用-N
或选项可恢复原始文件名。是压缩时的默认设置(因此始终保存原始文件名),但不是解压缩时的默认设置,因此必须明确使用。--name
gunzip
-N
gzip
gunzip
我对此进行了如下测试:
$ ls
test.txt
$ gzip test.txt
$ ls
test.txt.gz
$ mv test.txt.gz widget.gz
$ gunzip -N widget.gz
$ ls
test.txt
...这就是我们想要的结果。
答案2
gzip / gunzip(Linux Mint / Ubuntu 中的 1.6 版)不支持出现记住或使用原始文件名,但显然能经过一些基本测试后,我最初的答案是它没有保存文件名,但我被骗通过误导性的--list
输出(可能就像 OP 那样)。
手册页表明它可以保存并使用原始文件名,但即使使用该-N or --name
选项创建 .gz 文件,在列出(-l
)该 .gz 文件的内容时,该uncompressed_name
列也会列出当前文件名“base”。
$ echo test > t1
$ gzip -vkN t1
t1: -40.0% -- replaced with t1.gz
$ gzip -vl t1.gz
method crc date time compressed uncompressed ratio uncompressed_name
defla 3bb935c6 Jan 3 14:59 28 5 -40.0% t1
$ cp t1.gz N1.gz
$ gzip -vl N1.gz
method crc date time compressed uncompressed ratio uncompressed_name
defla 3bb935c6 Jan 3 15:04 28 5 -40.0% N1
除非您还可以-N
在测试/列出时使用该选项,然后它显示原始文件名
$ gzip -vlN t1.gz
method crc date time compressed uncompressed ratio uncompressed_name
defla 3bb935c6 Jan 3 14:59 28 5 -40.0% t1
$ gzip -vlN N1.gz
method crc date time compressed uncompressed ratio uncompressed_name
defla 3bb935c6 Jan 3 14:59 28 5 -40.0% t1
不使用该-N
选项解压也不会恢复原始文件名,
我不认为 gzip 曾经保存或使用过原始文件名,它更像是一种通常用于 .tar 文件的“一次一个文件”的压缩,当 tar 保存多个文件及其名称时,gzip 保存名称的实用性似乎有限。
其他压缩档案格式(例如 .zip、.7z)也能记住文件名,因为它们存档和压缩多个文件,就像一个 .tar.gz 文件。
说到加密,gpg 可以记住并使用原始文件名(当它-c
在单个文件上使用对称加密时,也应该适用于公钥加密)。