tarfile.extractall() 引发 IsADirectoryError 因为提取路径存在
tarfile.extractall() raises IsADirectoryError because extraction path exists
我无法提取生成的 tar.gz 文件,因为 extractall()
抱怨目标目录存在。但是,如果提取目录不存在,它只会生成一个空文件。
我在网上找到的所有关于提取 tarfile 的示例 use no parameters for tarfile.extractall()
(which means it attempts to extract it in the same directory and fails for me with IsADirectoryError
) or 。
这是使用 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 添加单个文件时使用的文件。
Changing/removing 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)
我无法提取生成的 tar.gz 文件,因为 extractall()
抱怨目标目录存在。但是,如果提取目录不存在,它只会生成一个空文件。
我在网上找到的所有关于提取 tarfile 的示例 use no parameters for tarfile.extractall()
(which means it attempts to extract it in the same directory and fails for me with IsADirectoryError
) or
这是使用 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 添加单个文件时使用的文件。
Changing/removing 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)