Попытка заархивировать файлы только в одном каталоге - PullRequest
1 голос
/ 02 ноября 2011

У меня есть путь / home / mine / new, который содержит файлы и подкаталоги.Я хочу заархивировать файлы, которые находятся только по этому пути (в «новом» пути), чтобы моя заархивированная папка содержала /new/file1, new/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 ]

2 голосов
/ 02 ноября 2011

Вы вызываете os.path.basename для переменной пути. Это означает, что если вы пытаетесь сжать файл new/dir1/file1, вы отбрасываете часть пути new/ и в итоге получаете dir1/file1, который не является допустимым путем относительно вашего текущего каталога.

Если вы просто удалите вызов на os.path.basename, он будет правильно архивировать файлы:

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

... хотя это может быть не то, что вы хотите в zipfile с точки зрения путей. Если вы запустите свой 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

Это создает ZIP-файл, который выглядит следующим образом:

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, чтобы убедиться, что вы имеете дело с файлами, а не с подкаталогами.

0 голосов
/ 02 ноября 2011

Похоже, что это может быть проблема с 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 голосов
/ 02 ноября 2011

Это потому, что 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)
...