python - tarfile.extractall() 引发 IsADirectoryError 因为提取路径存在

标签 python python-3.x tar

我无法提取生成的 tar.gz 文件,因为 extractall() 提示目标目录存在。但是,如果提取目录不存在,它只会生成一个空文件。

我在网上找到的有关提取 tar 文件的所有示例 use no parameters对于 tarfile.extractall() (这意味着它尝试将其提取到同一目录中,但因 IsADirectoryError 而失败)或 make sure to create the extraction path beforehand

这里使用的是 Python 3.5.2。

复制脚本:

#!/usr/bin/python3

import os, tarfile, tempfile

# Create a test directory
test_dir = os.path.join(os.path.expanduser('~'), 'tarfile-test')
os.makedirs(test_dir, exist_ok=True)
os.chdir(test_dir)

# Create empty files to include in the tarfile
open('1.txt', 'a').close()
open('2.txt', 'a').close()
open('3.txt', 'a').close()

# Create the tarfile
compressed_file = 'packet.tgz'
with tarfile.open(compressed_file, 'w:gz') as tar:
    for f in os.listdir():
        tar.add(f, arcname=os.path.sep)

# Now attempt to extract it in three different places: a local directory, a
# temporary directory and a non-existent directory

# Local directory
local_dir = 'local-extraction'
os.makedirs(local_dir, exist_ok=True)
try:
    with tarfile.open(compressed_file, 'r:gz') as tar:
        tar.extractall(path=local_dir)
        print('Extracted in local dir!')
except IsADirectoryError:
    print('Failed to extract in local directory')

# Temporary directory
try:
    with tempfile.TemporaryDirectory() as tmp_dir:
        with tarfile.open(compressed_file, 'r:gz') as tar:
            tar.extractall(path=tmp_dir)
            print('Extracted in temporary dir!')
except IsADirectoryError:
    print('Failed to extract in temporary directory')

# Non-existent directory. This does not throw an exception, but fails to extract
# the files
non_existent = 'non_existent_dir'
with tarfile.open(compressed_file, 'r:gz') as tar:
    tar.extractall(path=non_existent)
    if os.path.isdir(non_existent):
        print('Extracted in previously non-existent dir!')
    else:
        print('Not extracted in non-existent dir')

输出:

$ ./repro.py 
Failed to extract in local directory
Failed to extract in temporary directory
Not extracted in non-existent dir

如果我们检查 tarfile-test 的内容:

$ ll
total 16
drwxrwxr-x  3 user user 4096 Jul 11 08:38 ./
drwxr-xr-x 31 user user 4096 Jul 11 08:38 ../
-rw-rw-r--  1 user user    0 Jul 11 08:38 1.txt
-rw-rw-r--  1 user user    0 Jul 11 08:38 2.txt
-rw-rw-r--  1 user user    0 Jul 11 08:38 3.txt
drwxrwxr-x  2 user user 4096 Jul 11 08:38 local-extraction/
-rw-rw-r--  1 user user    0 Jul 11 08:38 non_existent_dir
-rw-rw-r--  1 user user  124 Jul 11 08:38 packet.tgz

non_existent_dir 是一个空文件,而不是目录。 local-extraction 为空。

我错过了什么?

最佳答案

看起来问题出在创建 tar.gz 文件时的 arcname 参数中。我(错误地)遵循了建议in this comment 。但是,这只应在打包目录时执行此操作,它会损坏添加单个文件时使用的 tar.gz 文件。

更改/删除 tarfile.add() 中的 arcname 参数可修复此问题:

# Create the tarfile
compressed_file = 'packet.tgz'
with tarfile.open(compressed_file, 'w:gz') as tar:
    for f in os.listdir():
        tar.add(f)

关于python - tarfile.extractall() 引发 IsADirectoryError 因为提取路径存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45027246/

相关文章:

python - 具有迭代器依赖性的矩阵乘法 - NumPy

python - 有没有办法在SSD上写入,如果在写入过程中断开连接,数据不会丢失?

python - 如何修改 gzip 压缩的 tar 文件中的文件?

python - 如果变量在被另一个函数访问 "initialized"之前被访问,则引发异常

unix - 使用 tar 时排除目录

pyspark - 在数据 block 上提取 tar.gz

python - 如何在 Django 中检查空 request.FILE

python - Psycopg2 不仅接受 None (Nonetype) 作为单元格条目,在使用 %s 但不使用 f-strings 时可以为 Null

python - Django 模板在 for 循环中计算总数

python - Windows Python 上的加密解密编码