Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何列出gz文件的内容而不在python中进行解压缩?_Python_Compression_Gzip_Extraction - Fatal编程技术网

如何列出gz文件的内容而不在python中进行解压缩?

如何列出gz文件的内容而不在python中进行解压缩?,python,compression,gzip,extraction,Python,Compression,Gzip,Extraction,我有一个.gz文件,需要使用python获取其中的文件名 这个问题与 唯一的区别是我的文件是.gz而不是.tar.gz,所以tarfile库在这里对我没有帮助 我正在使用请求库请求URL。响应是一个压缩文件 这是我用来下载文件的代码 response = requests.get(line.rstrip(), stream=True) if response.status_code == 200: with open(str(base_output_dir

我有一个
.gz
文件,需要使用python获取其中的文件名

这个问题与

唯一的区别是我的文件是
.gz
而不是
.tar.gz
,所以
tarfile
库在这里对我没有帮助

我正在使用
请求
库请求URL。响应是一个压缩文件

这是我用来下载文件的代码

response = requests.get(line.rstrip(), stream=True)
        if response.status_code == 200:
            with open(str(base_output_dir)+"/"+str(current_dir)+"/"+str(count)+".gz", 'wb') as out_file:
                shutil.copyfileobj(response.raw, out_file)
            del response
例如,此代码下载名为
1.gz
的文件。现在,如果我使用归档管理器打开文件,文件将包含类似于
my_latest_data.json

我需要提取文件,输出为
my\u latest\u data.json

下面是我用来提取文件的代码

inF = gzip.open(f, 'rb')
outfilename = f.split(".")[0]
outF = open(outfilename, 'wb')
outF.write(inF.read())
inF.close()
outF.close()

outputfilename
变量是我在脚本中提供的字符串,但我需要真实的文件名(
my\u latest\u data.json

,因为Gzip不是存档格式

这本身就是一个有点垃圾的解释,所以让我比在评论中更详细地解释一下

它只是压缩

“只是一个压缩系统”意味着Gzip操作输入字节(通常来自文件)并输出压缩字节。您无法知道其中的字节是表示多个文件还是仅表示一个文件——它只是一个已压缩的字节流。例如,这就是为什么可以通过网络接受gzip数据。它的bytes\u in->bytes\u out

什么是舱单?

清单是存档中的标头,用作存档的目录。请注意,现在我使用的是术语“归档”,而不是“压缩的字节流”。存档意味着它是清单引用的文件或段的集合——压缩的字节流就是字节流

Gzip里面到底是什么?

对.gz文件内容的简化描述如下:

  • 带有一个特殊数字的头,表示它的gzip、版本和时间戳(10字节)
  • 可选标题;通常包括原始文件名(如果压缩目标是文件)
  • 身体——一些压缩的有效载荷
  • 末尾的CRC-32校验和(8字节)
  • 就这样。没有舱单

    另一方面,归档格式内部将有一个清单。这就是焦油图书馆的用武之地。Tar只是一种将一堆位塞进单个文件的方法,并在前面放置一个清单,让您知道原始文件的名称以及它们在连接到归档文件之前的大小。因此,
    .tar.gz
    非常普遍

    有一些实用程序允许您一次解压缩gzip文件的一部分,或者只在内存中解压缩它,然后让您检查清单或其中可能包含的任何内容。但是任何清单的详细信息都是特定于其中包含的归档格式的


    请注意,这与zip归档不同。Zip是一种存档格式,因此包含清单。Gzip是一个压缩库,就像bzip2和friends一样。

    如另一个答案中所述,您的问题只有在去掉复数形式后才有意义:“我有一个
    .gz
    文件,我需要使用python获取其中的文件名。”

    gzip头中可能有文件名,也可能没有文件名。gzip实用程序通常会忽略标题中的名称,并解压缩到一个与
    .gz
    文件同名的文件中,但将
    .gz
    剥离。例如,您的
    1.gz
    将解压缩为名为
    1
    的文件,即使标题中包含文件名
    my_latest_data.json
    。gzip的-N选项将使用头中的文件名(以及头中的时间戳)(如果有)。因此
    gzip-dn1.gz
    将创建文件
    my_latest_data.json
    ,而不是
    1

    在Python中,可以通过手动处理头文件在头文件中找到文件名。您可以在中找到详细信息

  • 验证前三个字节是否为
    1f 8b 08
  • 保存第四个字节。称之为
    标志
    。如果
    flags&8
    为零,则放弃——头中没有文件名
  • 跳过接下来的六个字节
  • 如果
    标志&2
    不是零,则跳过两个字节
  • 如果
    标志&4
    不是零,则读取下两个字节。考虑到它们是以小尾端顺序排列的,从这两个字节中取一个整数,称之为
    xlen
    。然后跳过
    xlen
    字节
  • 我们已经知道
    flags&8
    不是零,因此您现在在文件名处。读取字节,直到达到零字节。这些字节(不包括零字节)是文件名

  • 注意:这个答案在Python 3中已经过时了


    使用MarkAdler回复中的提示和对gzip模块的一些检查,我设置了这个函数,从gzip文件中提取内部文件名。我注意到GzipFile对象有一个名为_read_gzip_header()的私有方法,它几乎可以获取文件名,所以我就是基于这个方法来做的

    import gzip
    
    def get_gzip_filename(filepath):
        f = gzip.open(filepath)
        f._read_gzip_header()
        f.fileobj.seek(0)
        f.fileobj.read(3)
        flag = ord(f.fileobj.read(1))
        mtime = gzip.read32(f.fileobj)
        f.fileobj.read(2)
        if flag & gzip.FEXTRA:
            # Read & discard the extra field, if present
            xlen = ord(f.fileobj.read(1))
            xlen = xlen + 256*ord(f.fileobj.read(1))
            f.fileobj.read(xlen)
        filename = ''
        if flag & gzip.FNAME:
            while True:
                s = f.fileobj.read(1)
                if not s or s=='\000':
                    break
                else:
                    filename += s
        return filename or None
    
    但是您可以采用链接周围的代码来使用它做其他事情

    如本页其他答案所述,此信息是可选的。但是,如果你需要查看它是否在那里,就不可能找回它

    导入结构
    def gzinfo(文件名):
    #从gzip.py第16行复制并粘贴
    FTEXT,FHCRC,FEXTRA,FNAME,FCOMMENT=1,2,4,8,16
    以fp形式打开(文件名为“rb”):
    #基本上是从GzipFile模块行429f复制+粘贴
    魔法=fp.read(2)
    如果magic==b“”:
    返回错误
    如果有魔法!=b'\037\213':
    raise VALUERROR('不是gzip文件(%r)')%magic