只压缩一个目录中的文件

1 投票
3 回答
2743 浏览
提问于 2025-04-17 05:29

我有一个路径是 /home/mine/new,这里面有一些文件和子目录。我想把这个路径下的文件压缩成一个 ZIP 文件,也就是说我希望压缩包里只包含 /new/file1new/file2 等文件。

我试过这样做:

import zipfile
import os,glob


def zipfunc(path, myzip):
    for path,dirs, files in os.walk(path):
            for file in files:
                if  os.path.isfile(os.path.join(path,file)):
                    myzip.write(os.path.join(os.path.basename(path), file))


if __name__ == '__main__':
    path=r'/home/ggous/new'
    myzip = zipfile.ZipFile('myzipped.zip', 'w')
    zipfunc(path,myzip)
    myzip.close()

但是它给了我一个错误提示
没有这样的文件或目录 new/file.doc

3 个回答

0

看起来可能是因为 zipfile.ZipFile.write() 这个方法需要一个完整的路径,而不是一个相对路径或者不完整的路径。你可以试着确保在压缩文件之前,使用的是完整的路径:

def zipfunc(path, myzip):
    for path,dirs, files in os.walk(path):
            for file in files:
                curpath = os.path.abspath(os.path.join(path, file))
                if  os.path.isfile(curpath):
                    myzip.write(curpath)
0

这是因为 os.walk 会深入到子目录中(而你的路径连接逻辑没有正确处理这个情况)。如果你不想进入子目录的话,可以用 glob.glob 来代替 os.walk

from os import path
import os

directory = r'/home/ggous/new'
for f in os.listdir(directory):
     if path.isfile(f):
         zipfile.write(os.path.basename(f), f)
2

你在使用 os.path.basename 这个函数处理路径变量。这意味着,如果你想压缩文件 new/dir1/file1,你会把路径中的 new/ 部分去掉,最后得到 dir1/file1,但这个路径在你当前的目录下并不有效。

如果你直接去掉对 os.path.basename 的调用,文件就会正确地被压缩:

myzip.write(os.path.join(path, file))

...不过这样可能不是你想要的压缩包路径。如果你从顶层目录内部开始使用 os.walk,你可能会得到你想要的结果:

if __name__ == '__main__':
    path=os.path.join(os.getcwd(), 'new')
    myzip = zipfile.ZipFile('myzipped.zip', 'w')

    # Change into the top level directory.
    os.chdir(path)

    zipfunc('.',myzip)
    myzip.close()

假设有这样的文件结构:

/home/lars/new
  file1
  file2
  dir1/
    file1
    file2
    file3

这样会创建一个看起来像这样的压缩包:

Archive:  myzipped.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       29  11-02-2011 09:14   file1
       29  11-02-2011 09:14   file2
       29  11-02-2011 09:14   dir1/file3
       29  11-02-2011 09:14   dir1/file1
       29  11-02-2011 09:14   dir1/file2
---------                     -------
      145                     5 files

如果你真正的目标只是压缩顶层的文件,而不想进入任何子目录,那么其实你不需要使用 os.walk。你可以直接用 os.listdir,再用 os.path.isfile 来确保你处理的是文件而不是子目录。

撰写回答