Python 压缩文件并避免目录结构

Python 压缩文件并避免目录结构,python,zip,Python,Zip,我有一个Python脚本可以压缩文件(new.txt): 当我这样做的时候,我得到了zip文件。但是当我试图解压文件时,我得到了一系列目录中的文本文件,这些目录对应于文件的路径,即我在结果目录中看到一个名为根的文件夹,以及其中的更多目录,即 /root/files/result/new.zip 当我解压new.zip时,我有一个目录结构 /root/files/result/root/files/result/new.txt 有没有一种方法可以压缩,这样当我解压缩时,我只会得到new.txt

我有一个Python脚本可以压缩文件(
new.txt
):

当我这样做的时候,我得到了zip文件。但是当我试图解压文件时,我得到了一系列目录中的文本文件,这些目录对应于文件的路径,即我在
结果
目录中看到一个名为
的文件夹,以及其中的更多目录,即

/root/files/result/new.zip
当我解压new.zip时,我有一个目录结构

/root/files/result/root/files/result/new.txt
有没有一种方法可以压缩,这样当我解压缩时,我只会得到
new.txt

换句话说,我有
/root/files/result/new.zip
,当我解压
new.zip时,它应该是

/root/files/results/new.txt
zipfile.write()
方法采用可选的
arcname
参数,该参数指定zipfile中的文件名

我认为您需要对目标进行修改,否则它将复制目录。使用:
arcname
来避免它。试着这样做:

import os
import zipfile

def zip(src, dst):
    zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)
    abs_src = os.path.abspath(src)
    for dirname, subdirs, files in os.walk(src):
        for filename in files:
            absname = os.path.abspath(os.path.join(dirname, filename))
            arcname = absname[len(abs_src) + 1:]
            print 'zipping %s as %s' % (os.path.join(dirname, filename),
                                        arcname)
            zf.write(absname, arcname)
    zf.close()

zip("src", "dst")

查看Zipfile.write的文档

write(文件名[,arcname[,压缩类型]])写入该文件 将文件名命名为归档文件,并将归档文件名命名为arcname(通过 默认情况下,这将与文件名相同,但没有驱动器号 并移除引导路径分隔符)

请尝试以下操作:

import zipfile
import os
filename = 'foo.txt'

# Using os.path.join is better than using '/' it is OS agnostic
path = os.path.join(os.path.sep, 'tmp', 'bar', 'baz', filename)
zip_filename = os.path.splitext(filename)[0] + '.zip'
zip_path = os.path.join(os.path.dirname(path), zip_filename)

# If you need exception handling wrap this in a try/except block
with zipfile.ZipFile(zip_path, 'w') as zf:
    zf.write(path, zip_filename)

底线是,如果您不提供存档名称,则文件名将用作存档名称,它将包含文件的完整路径。

为了更清楚地说明

目录结构:

/Users
 └── /user
 .    ├── /pixmaps
 .    │    ├── pixmap_00.raw
 .    │    ├── pixmap_01.raw
      │    ├── /jpeg
      │    │    ├── pixmap_00.jpg
      │    │    └── pixmap_01.jpg
      │    └── /png
      │         ├── pixmap_00.png
      │         └── pixmap_01.png
      ├── /docs
      ├── /programs
      ├── /misc
      .
      .
      .
CompressedDir.zip
.
└── /Users
     └── /user
          └── /pixmaps
               ├── pixmap_00.raw
               ├── pixmap_01.raw
               ├── /jpeg
               │    ├── pixmap_00.jpg
               │    └── pixmap_01.jpg
               └── /png
                    ├── pixmap_00.png
                    └── pixmap_01.png
CompressedDir.zip
.
└── /pixmaps
     ├── pixmap_00.raw
     ├── pixmap_01.raw
     ├── /jpeg
     │    ├── pixmap_00.jpg
     │    └── pixmap_01.jpg
     └── /png
          ├── pixmap_00.png
          └── pixmap_01.png
感兴趣的目录:/Users/user/pixmap

第一次尝试

import os
import zipfile

TARGET_DIRECTORY = "/Users/user/pixmaps"
ZIPFILE_NAME = "CompressedDir.zip"

def zip_dir(directory, zipname):
    """
    Compress a directory (ZIP file).
    """
    if os.path.exists(directory):
        outZipFile = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)

        for dirpath, dirnames, filenames in os.walk(directory):
            for filename in filenames:

                filepath   = os.path.join(dirpath, filename)
                outZipFile.write(filepath)

        outZipFile.close()




if __name__ == '__main__':
    zip_dir(TARGET_DIRECTORY, ZIPFILE_NAME)
ZIP文件结构:

/Users
 └── /user
 .    ├── /pixmaps
 .    │    ├── pixmap_00.raw
 .    │    ├── pixmap_01.raw
      │    ├── /jpeg
      │    │    ├── pixmap_00.jpg
      │    │    └── pixmap_01.jpg
      │    └── /png
      │         ├── pixmap_00.png
      │         └── pixmap_01.png
      ├── /docs
      ├── /programs
      ├── /misc
      .
      .
      .
CompressedDir.zip
.
└── /Users
     └── /user
          └── /pixmaps
               ├── pixmap_00.raw
               ├── pixmap_01.raw
               ├── /jpeg
               │    ├── pixmap_00.jpg
               │    └── pixmap_01.jpg
               └── /png
                    ├── pixmap_00.png
                    └── pixmap_01.png
CompressedDir.zip
.
└── /pixmaps
     ├── pixmap_00.raw
     ├── pixmap_01.raw
     ├── /jpeg
     │    ├── pixmap_00.jpg
     │    └── pixmap_01.jpg
     └── /png
          ├── pixmap_00.png
          └── pixmap_01.png
避免完整目录路径

def zip_dir(directory, zipname):
    """
    Compress a directory (ZIP file).
    """
    if os.path.exists(directory):
        outZipFile = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)

        # The root directory within the ZIP file.
        rootdir = os.path.basename(directory)

        for dirpath, dirnames, filenames in os.walk(directory):
            for filename in filenames:

                # Write the file named filename to the archive,
                # giving it the archive name 'arcname'.
                filepath   = os.path.join(dirpath, filename)
                parentpath = os.path.relpath(filepath, directory)
                arcname    = os.path.join(rootdir, parentpath)

                outZipFile.write(filepath, arcname)

    outZipFile.close()




if __name__ == '__main__':
    zip_dir(TARGET_DIRECTORY, ZIPFILE_NAME)
ZIP文件结构:

/Users
 └── /user
 .    ├── /pixmaps
 .    │    ├── pixmap_00.raw
 .    │    ├── pixmap_01.raw
      │    ├── /jpeg
      │    │    ├── pixmap_00.jpg
      │    │    └── pixmap_01.jpg
      │    └── /png
      │         ├── pixmap_00.png
      │         └── pixmap_01.png
      ├── /docs
      ├── /programs
      ├── /misc
      .
      .
      .
CompressedDir.zip
.
└── /Users
     └── /user
          └── /pixmaps
               ├── pixmap_00.raw
               ├── pixmap_01.raw
               ├── /jpeg
               │    ├── pixmap_00.jpg
               │    └── pixmap_01.jpg
               └── /png
                    ├── pixmap_00.png
                    └── pixmap_01.png
CompressedDir.zip
.
└── /pixmaps
     ├── pixmap_00.raw
     ├── pixmap_01.raw
     ├── /jpeg
     │    ├── pixmap_00.jpg
     │    └── pixmap_01.jpg
     └── /png
          ├── pixmap_00.png
          └── pixmap_01.png
改变

zf.write(tofile, zipfile_dir)
比如说

zf.write("/root/files/result/root/files/result/new.txt", "/root/files/results/new.txt")

您可以使用以下方法仅隔离源文件的文件名:

name_file_only= name_full_path.split(os.sep)[-1]
例如,如果
name\u full\u path
/root/files/results/myfile.txt
,那么
name\u file\u only
将是
myfile.txt
。要将myfile.txt压缩到存档的根目录
zf
,您可以使用:

zf.write(name_full_path, name_file_only)

我面临同样的问题,我用
writestr
解决它。您可以这样使用它:

import os
import zipfile

def zip(src, dst):
    zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)
    abs_src = os.path.abspath(src)
    for dirname, subdirs, files in os.walk(src):
        for filename in files:
            absname = os.path.abspath(os.path.join(dirname, filename))
            arcname = absname[len(abs_src) + 1:]
            print 'zipping %s as %s' % (os.path.join(dirname, filename),
                                        arcname)
            zf.write(absname, arcname)
    zf.close()

zip("src", "dst")

zipObject.writestr(,)
write方法中的
arcname
参数指定zipfile中的文件名:

import os
import zipfile

# 1. Create a zip file which we will write files to
zip_file = "/home/username/test.zip"
zipf = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)

# 2. Write files found in "/home/username/files/" to the test.zip
files_to_zip = "/home/username/files/"
for file_to_zip in os.listdir(files_to_zip):

    file_to_zip_full_path = os.path.join(files_to_zip, file_to_zip)

    # arcname argument specifies what will be the name of the file inside the zipfile
    zipf.write(filename=file_to_zip_full_path, arcname=file_to_zip)

zipf.close()
我们可以用这个

import os
# single File
os.system(f"cd {destinationFolder} && zip fname.zip fname") 
# directory
os.system(f"cd {destinationFolder} && zip -r folder.zip folder") 

对我来说,这是可行的。

如果您想要一种优雅的方式来使用
pathlib
您可以这样使用它:

从pathlib导入路径
进口拉链
def zip_目录(路径到:路径):
zip_file=Path(Path_to_zip)。带有后缀('.zip')
z=zipfile.zipfile(压缩文件'w',zipfile.zip_已压缩)
对于列表中的f(路径到zip.rglob('*.'):
z、 写入(f,arcname=f.relative_to(path_to_zip))

最后,它比预期的要简单,我使用参数“arcname”将模块配置为“file\u to\u be\u zipped.txt”,因此文件夹不会出现在我的最终压缩文件中:

mmpk_zip_file = zipfile.ZipFile("c:\\Destination_folder_name\newzippedfilename.zip", mode='w', compression=zipfile.ZIP_DEFLATED)
mmpk_zip_file.write("c:\\Source_folder_name\file_to_be_zipped.txt", "file_to_be_zipped.txt")
mmpk_zip_file.close()

@用户34551743,太棒了!如果你有一个不存在的问题,那么我认为你应该问这个问题,然后回答你自己的问题。你会帮助其他人(甚至你自己在未来)当他们搜索一个更相关的问题。我不明白为什么你需要指定ARCNEX以避免它遍历所有的父文件夹到根,如果我给一个文件路径,为什么不只是考虑文件?你可以改变ARCNEX= ABSMEND[LEN(AbsSySRC)+ 1:]对于arcname=os.path.basename(absname),这是非常棒的!