Python 3: 在不写入磁盘的情况下提取 tar.gz 存档
Python 3: Extract tar.gz archive without writing to disk
如标题所说,有没有办法在不将文件写入磁盘的情况下提取 tar.gz 存档(存档是从互联网上下载的)。在 bash 或任何其他 shell 中,我可以将 curl 或 wget 的输出通过管道传输到 tar:
curl -L "https://somewebsite.com/file.tar.gz" | tar xzf -
我也可以在 python 中做这样的事情吗?
编辑:我正在使用 urllib 下载数据。我目前正在做这样的事情来下载和写入文件:
from urllib.request import urlopen
filename = "/home/bob/file.tar.gz"
url = "https://website.com/file.tar.gz"
file = open(filename, "wb")
file.write(urlopen(url).read())
file.close
无需将 TAR 文件写入磁盘,您可以使用 python subprocess 模块为您执行 运行 shell 命令:
import subprocess
# some params
shell_cmd = 'curl -L "https://somewebsite.com/file.tar.gz" | tar xzf -'
i_trust_this_string_cmd = True
throw_error_on_fail = True
timeout_after_seconds = 10 # or None
convert_output_from_bytes_to_string = True
#
# run shell as subprocesses to this one and get results
cp = subprocess.run(
[shell_cmd],
shell=i_trust_this_string_cmd,
check=throw_error_on_fail,
timeout=timeout_after_seconds,
text=convert_output_from_bytes_to_string
)
#status_code = cp.returncode
try:
cp.check_returncode() # triggers exceptions if errors occurred
print(cp.stdout) # if you want to see the output (text in this case)
except subprocess.CalledProcessError as cpe:
print(cpe)
except subprocess.TimeoutExpired as te:
print(te)
如果您想要更多控制,可以为 STDOUT、STDERR 提供一个 PIPE,例如
with open('/tmp/stdout.txt', 'w+') as stdout:
with open('/tmp/stderr.txt', 'w+') as stderr:
cp = subprocess.run([...], stdout=stdout, stderr=stderr)
...
在 kenny 评论的帮助下,我通过解析从 urlopen 获得的数据、使用 BytesIO 并将其用作 tarfile.open:
的 fileobj 参数来完成我想做的事情
from urllib.request import urlopen
import tarfile
from io import BytesIO
r = urlopen("https://url/file.tar.gz")
t = tarfile.open(name=None, fileobj=BytesIO(r.read()))
t.extractall("/somedirectory/")
t.close()
如标题所说,有没有办法在不将文件写入磁盘的情况下提取 tar.gz 存档(存档是从互联网上下载的)。在 bash 或任何其他 shell 中,我可以将 curl 或 wget 的输出通过管道传输到 tar:
curl -L "https://somewebsite.com/file.tar.gz" | tar xzf -
我也可以在 python 中做这样的事情吗?
编辑:我正在使用 urllib 下载数据。我目前正在做这样的事情来下载和写入文件:
from urllib.request import urlopen
filename = "/home/bob/file.tar.gz"
url = "https://website.com/file.tar.gz"
file = open(filename, "wb")
file.write(urlopen(url).read())
file.close
无需将 TAR 文件写入磁盘,您可以使用 python subprocess 模块为您执行 运行 shell 命令:
import subprocess
# some params
shell_cmd = 'curl -L "https://somewebsite.com/file.tar.gz" | tar xzf -'
i_trust_this_string_cmd = True
throw_error_on_fail = True
timeout_after_seconds = 10 # or None
convert_output_from_bytes_to_string = True
#
# run shell as subprocesses to this one and get results
cp = subprocess.run(
[shell_cmd],
shell=i_trust_this_string_cmd,
check=throw_error_on_fail,
timeout=timeout_after_seconds,
text=convert_output_from_bytes_to_string
)
#status_code = cp.returncode
try:
cp.check_returncode() # triggers exceptions if errors occurred
print(cp.stdout) # if you want to see the output (text in this case)
except subprocess.CalledProcessError as cpe:
print(cpe)
except subprocess.TimeoutExpired as te:
print(te)
如果您想要更多控制,可以为 STDOUT、STDERR 提供一个 PIPE,例如
with open('/tmp/stdout.txt', 'w+') as stdout:
with open('/tmp/stderr.txt', 'w+') as stderr:
cp = subprocess.run([...], stdout=stdout, stderr=stderr)
...
在 kenny 评论的帮助下,我通过解析从 urlopen 获得的数据、使用 BytesIO 并将其用作 tarfile.open:
的 fileobj 参数来完成我想做的事情from urllib.request import urlopen
import tarfile
from io import BytesIO
r = urlopen("https://url/file.tar.gz")
t = tarfile.open(name=None, fileobj=BytesIO(r.read()))
t.extractall("/somedirectory/")
t.close()