压缩目录并在之后使用 shutil 删除它
Zip a directory and delete it right afterwards using shutil
我正在尝试压缩给定目录,然后立即删除该目录。
因此我正在使用 shutil
模块。
我为此实现的方法如下所示:
def _zip(fulldname, delete_after=False):
"""
Zip a directory
:param dname: The full name of the directory
:type dname: str
:param delete_after: Delete the directory after it has been zipped?
:type delete_after: bool
:return: the full name of the zip file
:rtype: str
"""
if not os.path.isdir(fulldname):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
fulldname)
fullzipfname = shutil.make_archive(fulldname, "zip", root_dir=fulldname,
base_dir="./")
if delete_after:
shutil.rmtree(fulldname)
return fullzipfname
当我执行它时,我要么得到以下错误,要么该方法永远运行(即卡在 shutil.rmtree()
方法):
File "/media/sf_projects/robot_framework/rfw_rest_api/src/main/rfw_rest_api/rfw_rest_api.py", line 126, in exec_robot
output_arc = core._zip(proc_output_dir, delete_after=True)
File "/media/sf_projects/robot_framework/rfw_rest_api/src/main/core.py", line 147, in _zip
shutil.rmtree(fulldname)
File "/usr/lib/python3.7/shutil.py", line 498, in rmtree
onerror(os.rmdir, path, sys.exc_info())
File "/usr/lib/python3.7/shutil.py", line 496, in rmtree
os.rmdir(path)
OSError: [Errno 26] Text file busy: '../../output/pcap_based_fuzzer_210127_120207'
我做错了什么?
似乎这个程序(或另一个进程)正在访问 fulldname
目录中的文件,而您正试图删除它。从“Text file busy”错误判断,该文件很可能是正在执行的二进制文件。我会确保调用该函数时,该目录中的任何文件都不会在程序中保持打开状态。
另外,根据docs,make_archive
的base_dir
参数必须相对于root_dir
参数。你确定变量 fulldname
和它持有的路径满足这个 属性?
我终于找到了一个完全避免shutil
:
的解决方案
def _zip(fulldname, delete_after=False):
"""
Zip a directory
:param fulldname: The full name of the directory
:type fulldname: str
:param delete_after: Delete the directory after it has been zipped?
:type delete_after: bool
:return: the name of the zip file
:rtype: str
"""
if not os.path.isdir(fulldname):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
fulldname)
fullzipfname = fulldname + ".zip"
with zipfile.ZipFile(fullzipfname, "w", zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(fulldname):
for _dir in dirs:
zipf.write(os.path.join(root, _dir),
os.path.relpath(os.path.join(root, _dir),
os.path.join(fulldname)))
for file in files:
zipf.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file),
os.path.join(fulldname)))
logger.debug(f"Created zip directory {fullzipfname}")
if delete_after:
for root, dirs, files in os.walk(fulldname, topdown=False):
for file in files:
os.remove(os.path.join(root, file))
for _dir in dirs:
os.rmdir(os.path.join(root, _dir))
os.rmdir(fulldname)
logger.debug(f"Removed original directory {fulldname}")
return fullzipfname.split(os.path.sep)[-1]
我还注意到 shutil
的 make_archive
有时会永远运行。
尽管在大多数情况下使用 os.walk()
和 zipfile.ZipFile
并没有明显加快,但它似乎仍然更可靠。
我正在尝试压缩给定目录,然后立即删除该目录。
因此我正在使用 shutil
模块。
我为此实现的方法如下所示:
def _zip(fulldname, delete_after=False):
"""
Zip a directory
:param dname: The full name of the directory
:type dname: str
:param delete_after: Delete the directory after it has been zipped?
:type delete_after: bool
:return: the full name of the zip file
:rtype: str
"""
if not os.path.isdir(fulldname):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
fulldname)
fullzipfname = shutil.make_archive(fulldname, "zip", root_dir=fulldname,
base_dir="./")
if delete_after:
shutil.rmtree(fulldname)
return fullzipfname
当我执行它时,我要么得到以下错误,要么该方法永远运行(即卡在 shutil.rmtree()
方法):
File "/media/sf_projects/robot_framework/rfw_rest_api/src/main/rfw_rest_api/rfw_rest_api.py", line 126, in exec_robot
output_arc = core._zip(proc_output_dir, delete_after=True)
File "/media/sf_projects/robot_framework/rfw_rest_api/src/main/core.py", line 147, in _zip
shutil.rmtree(fulldname)
File "/usr/lib/python3.7/shutil.py", line 498, in rmtree
onerror(os.rmdir, path, sys.exc_info())
File "/usr/lib/python3.7/shutil.py", line 496, in rmtree
os.rmdir(path)
OSError: [Errno 26] Text file busy: '../../output/pcap_based_fuzzer_210127_120207'
我做错了什么?
似乎这个程序(或另一个进程)正在访问 fulldname
目录中的文件,而您正试图删除它。从“Text file busy”错误判断,该文件很可能是正在执行的二进制文件。我会确保调用该函数时,该目录中的任何文件都不会在程序中保持打开状态。
另外,根据docs,make_archive
的base_dir
参数必须相对于root_dir
参数。你确定变量 fulldname
和它持有的路径满足这个 属性?
我终于找到了一个完全避免shutil
:
def _zip(fulldname, delete_after=False):
"""
Zip a directory
:param fulldname: The full name of the directory
:type fulldname: str
:param delete_after: Delete the directory after it has been zipped?
:type delete_after: bool
:return: the name of the zip file
:rtype: str
"""
if not os.path.isdir(fulldname):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
fulldname)
fullzipfname = fulldname + ".zip"
with zipfile.ZipFile(fullzipfname, "w", zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(fulldname):
for _dir in dirs:
zipf.write(os.path.join(root, _dir),
os.path.relpath(os.path.join(root, _dir),
os.path.join(fulldname)))
for file in files:
zipf.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file),
os.path.join(fulldname)))
logger.debug(f"Created zip directory {fullzipfname}")
if delete_after:
for root, dirs, files in os.walk(fulldname, topdown=False):
for file in files:
os.remove(os.path.join(root, file))
for _dir in dirs:
os.rmdir(os.path.join(root, _dir))
os.rmdir(fulldname)
logger.debug(f"Removed original directory {fulldname}")
return fullzipfname.split(os.path.sep)[-1]
我还注意到 shutil
的 make_archive
有时会永远运行。
尽管在大多数情况下使用 os.walk()
和 zipfile.ZipFile
并没有明显加快,但它似乎仍然更可靠。