Search code examples
pythonpython-zipfile

How to zip files that ends with certain extension


I want to get all files in a directory (I reached it after doing several for loops - hence fourth.path) that ends with .npy or with csv and then zip those files. My code is running putting one file only in the zip file. What am I doing wrong? I tried to change my indents, but no zip file is being created

import json
import os
import zipfile
import zlib

directory = os.path.join(os.getcwd(), 'recs')
radarfolder = 'RadarIfxAvian'
file = os.listdir(directory)

def r(p, name):
    p = os.path.join(p, name)
    return p.replace("/", "\\") 

#This code will list all json files in e    ach file
for first in os.scandir(directory):
    if first.is_dir():
        for second in os.scandir(first.path):
            if second.is_dir():
               for third in os.scandir(second.path):
                if third.is_dir():
                    radar_folder_name = ''
                    list_files = ()
                    for fourth in os.scandir(third.path):
                        if fourth.is_dir():
                            if radarfolder in fourth.path:
                                radar_folder_name = fourth.path
                                print(radar_folder_name)
                                list_files = ()
                                for file in os.listdir(fourth.path):
                                    if file.endswith(".npy") | file.endswith(".csv"):
                                        list_files = (file)
                                        print(list_files)
                                    with zipfile.ZipFile(radar_folder_name +'\\' +'radar.zip', 'w', compression=zipfile.ZIP_DEFLATED ) as zipMe:
                                        zipMe.write(radar_folder_name +'\\' +list_files)            
                                        zipMe.close()

I tried to change my indents either resulting in error: TypeError: can only concatenate str (not "tuple") to str or no zip file being created


Solution

  • As I said in my second comment, your problem comes from the 'w' argument in your zipping statement. It causes the zip to be overwritten every time it's opened, which you do for each file you zip in. You can fix this 2 ways (at least):

    • Replace 'w' with 'a'; this way the files will be appended to your zip (with the side effect that, if you do this several times, files will be added more than once).
    • Keep the 'w', but only open the zip once, having listed all the files you want to zip before. See my code below.

    I've taken the liberty to rewrite the part of your code where you look for the 'RadarIfxAvian' folder, since embedded for are clumsy (and if your folder structure changes, they might not work), replacing it with a multi-purpose recursive function.

    Note that the folder structure will be included in the .zip; if you want to zip only the files themselves, consider doing os.chdir(radar_folder_name) before zipping the files.

    # This function recursively looks for the 'filename' file or folder
    # under 'start_path' and returns the full path, or an empty string if not found.
    def find_file(start_path, filename):
        if filename in os.listdir(start_path):
            return start_path + '/' + filename
        for file in os.scandir(start_path):
            if not file.is_dir():
                continue
            if (deep_path:=find_file(start_path + '/' + file.name, filename)):
                return deep_path
        return ''
    
    directory = os.path.join(os.getcwd(), 'recs')
    radarfolder = 'RadarIfxAvian'
    
    radar_folder_name = find_file(directory, radarfolder)
    print(radar_folder_name)
    list_files = []
    for file in os.listdir(radar_folder_name):
        if file.endswith(".npy") or file.endswith(".csv"):
            list_files.append(file)
    with zipfile.ZipFile(radar_folder_name + '/' + 'radar.zip', 'w', compression=zipfile.ZIP_DEFLATED ) as zipMe:
        for file in list_files:
            zipMe.write(radar_folder_name + '/' + file)