0

I have a few zip files that I need to delete programmatically in Python 3. I do not need to open them first at all: I can determine if I want to delete them solely based on their filename. In scanning SO for this question, I note the following unsatisfactory questions (unsatisfactory, as in, I've tried all their approaches with no success):

  1. Removing path from a zip file using python
  2. Python zipfile doesn't release zip file
  3. Unable to remove zipped file after unzipping
  4. os.remove() in windows gives "[Error 32] being used by another process"

In particular, calling the close() method or opening the file in a with clause does not release whatever Windows lock there is. The simplest MWE I can dream up is this:

import os
file_path = r'C:\Users\akeister\Desktop\Tatsuro 1.2.0.zip'
os.remove(file_path)

This code produces:

PermissionError: [WinError 32] The process cannot access the file because it 
is being used by another process: 'C:\\Users\\akeister\\Desktop\\Tatsuro 
1.2.0.zip'

I get the same error if I try

import os
file_path = r'C:\Users\akeister\Desktop\Tatsuro 1.2.0.zip'
with open(file_path) as f:
    f.close()
os.remove(file_path)

or

import gzip
import os
file_path = r'C:\Users\akeister\Desktop\Tatsuro 1.2.0.zip'
with gzip.GzipFile(file_path) as f:
    f.close()
os.remove(file_path)

or

import zipfile
import os
zipped_file = r'C:\Users\akeister\Desktop\Tatsuro 1.2.0.zip'
with zipfile.ZipFile(zipped_file) as zip_file:
    for member in zip_file.namelist():
        filename = os.path.basename(member)
        if not filename:
            continue
        source = zip_file.open(member)
os.remove(zipped_file)

There's no command prompt open to the desktop, and there's no Windows Explorer window open to the desktop.

I suspect part of my problem is that the files may be gzip files, and not regular zip files. I'm not entirely sure which they are. I generated the zip files (at least, they have a .zip extension) in LabVIEW 2015 using the built-in zip functions. It's not clear from the LabVIEW documentation which kind of compression the zip functions use.

What is the solution to my problem? Thanks in advance for your time!

Adrian Keister
  • 842
  • 3
  • 15
  • 33
  • Do you close the ZIP file after creating it in LabVIEW? http://zone.ni.com/reference/en-XX/help/371361M-01/glang/close_zip_file/ – Lithis Jul 31 '18 at 17:22
  • @Lithis: Yes, I do. I think the posted answer is on the right track. – Adrian Keister Jul 31 '18 at 17:32
  • 1
    @AdrianKeister Can you post a picture please of the LV code that created the .zip file? It would be useful to see if there's something particular in there that would make LV hold the file open. – srm Aug 01 '18 at 01:24

2 Answers2

2

I believe the solution is in addressing the root cause of the error you get:

PermissionError: [WinError 32] The process cannot access the file because it 
is being used by another process: 'C:\\Users\\akeister\\Desktop\\Tatsuro 
1.2.0.zip'

It appears to not be so much of a Python problem as much as it appears to be a Windows and/or LabVIEW problem.

It's normal behavior for a file to not be able to be deleted if another process has a lock on it. So, releasing the lock (which it seems LabVIEW is still holding) is a must.

I recommend identifying the LabVIEW PID and either stopping or restarting LABVIEW.

You might try incorporating https://null-byte.wonderhowto.com/forum/kill-processes-windows-using-python-0160688/ or https://github.com/cklutz/LockCheck (a Windows based program which identifies file locks).

If you can incorporate either into your Python program to shutdown or restart the locking process then the zip file should be removable.

Don
  • 554
  • 4
  • 8
0

For completeness, I will post the code that worked (after completely closing down LabVIEW):

import shutil
import os
import tkinter as tk


""" ----------------- Get delete_zip_files variable. --------------- """


delete_zip_files = False

root= tk.Tk() # create window

def delete_button():
    global delete_zip_files

    delete_zip_files = True
    root.destroy()

def leave_button():
    global delete_zip_files

    delete_zip_files = False
    root.destroy()


del_button = tk.Button(root, text='Delete Zip Files',
                   command=delete_button)
del_button.pack()  

lv_button = tk.Button(root, text='Leave Zip Files',
                  command=leave_button)
lv_button.pack()                     

root.mainloop()

print(str(delete_zip_files))


""" ----------------- List files in user's desktop. ---------------- """


# Desktop path is os.path.expanduser("~/Desktop")
# List contents of a directory: os.listdir('directory here')
desktop_path = os.path.expanduser("~/Desktop")

for filename in os.listdir(desktop_path):
    if filename.startswith('Tatsuro') or \
            filename.startswith('TestScript'):
        # Get full path to file.
        file_path = os.path.join(desktop_path, filename)

        if filename.endswith('2015'):
            # It's a folder. Empty the folder, then delete the folder:
            shutil.rmtree(file_path)

        if filename.endswith('.zip'):
            # Get desired folder name. 
            target_folder_name = filename.split('.zip')[0]
            target_folder_path = os.path.join(desktop_path, 
                                              target_folder_name)

            # Now we process. Unzip and delete.
            shutil.unpack_archive(file_path, target_folder_path)

            if delete_zip_files:

                # Now we delete if the user chose that.
                os.remove(file_path)
Adrian Keister
  • 842
  • 3
  • 15
  • 33