使用Python脚本删除文件时出现错误

1 投票
3 回答
69 浏览
提问于 2025-04-13 19:37

我正在运行一个Python脚本,这个脚本的功能是从一个文件夹里删除文件。我是在一个虚拟机里运行这个脚本的……但是我遇到了以下错误:

Traceback (most recent call last):
  File "C:\Users\Desktop\hyta\python_scripts\python_scr\file_delete.py", line 66, in <module
    compare_and_delete_sql_files(folder_a, folder_b, output_csv, sql_filenames)
  File "C:\Users\Desktop\hyta\python_scripts\python_scr\file_delete.py", line 53, in compare_and_delete_sql_files
    os.remove(os.path.join(folder_b, filename))
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\Users\Desktop\hyta\python_scripts\python_scr/folder_b\\scrum_1.sql'

我的代码:

import os
import csv

def extract_sql_filenames_from_yaml(yaml_file):
    sql_filenames = {}
    with open(yaml_file, 'r') as file:
        is_sql_section = False
        for line in file:
            line = line.strip()
            if line == 'sql:':
                is_sql_section = True
            elif is_sql_section and line.startswith('- name:') and not line.startswith('#'):
                filename = line.split(':')[-1].strip()
                if filename.endswith('.sql'):
                    sql_filenames[filename] = sql_filenames.get(filename, 0) + 1
            elif line.startswith('-') and not line.startswith('#'):
                is_sql_section = False
    return sql_filenames

def compare_and_delete_sql_files(folder_a, folder_b, output_csv, sql_filenames):
    processed_filenames = set()  # To keep track of processed filenames

    # Initialize CSV file writer
    with open(output_csv, 'w', newline='') as csvfile:
        fieldnames = ['SQL File Name', 'Occurrences', 'Match Status', 'Delete Status']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()

        # Iterate through each SQL filename extracted from YAML
        for filename, occurrences in sql_filenames.items():
            # Skip processing if the filename has already been processed
            if filename in processed_filenames:
                continue

            # Mark the filename as processed
            processed_filenames.add(filename)

            sql_file_a = os.path.join(folder_a, filename)
            match_status = 'Not Matched'
            delete_status = 'Not Deleted'

            # Check if the file exists in folder_a
            if os.path.exists(sql_file_a):
                # Compare with folder_b if necessary
                if os.path.exists(os.path.join(folder_b, filename)):
                    with open(sql_file_a, 'r') as f_a, open(os.path.join(folder_b, filename), 'r') as f_b:
                        lines_a = f_a.readlines()
                        lines_b = f_b.readlines()
                        if lines_a == lines_b:
                            match_status = 'Matched'
                            delete_status = 'Deleted'
                            # Delete file from folder_b
                            os.remove(os.path.join(folder_b, filename))

            # Write to CSV
            writer.writerow({'SQL File Name': filename, 'Occurrences': occurrences,
                             'Match Status': match_status, 'Delete Status': delete_status})

# Example usage
folder_a = '/path/to/folder/a'
folder_b = '/path/to/folder/b'
output_csv = 'comparison_results.csv'
yaml_file = 'example.yaml'

sql_filenames = extract_sql_filenames_from_yaml(yaml_file)
compare_and_delete_sql_files(folder_a, folder_b, output_csv, sql_filenames)

3 个回答

0

一些初步的问题:

  • 文件路径中应该有正斜杠吗(请看下面的文件路径参考)?
  • 你是否在其他线程或进程中打开了这个文件(假设你在电脑上没有打开它)?
  • 错误是在你处理的第一个SQL脚本上,还是最后一个?或者是你成功处理了几个SQL脚本,但在这个特定的脚本文件上出错了?

如果你有更多的信息或者在脚本操作中有记录,请告诉我。

文件路径参考: C:\Users\Desktop\hyta\python_scripts\python_scr**/**folder_b\scrum_1.sql

2

在Windows系统中,如果一个文件在其他程序中被打开,你是无法删除它的,这就是所谓的[WinError 32].[microsoft.com]

即使你自己没有打开这个文件,它也可能在其他程序中被打开,所以在Windows上使用os.remove()删除文件并不一定能成功。

在你的情况中,file是在你自己的程序中被open的,而你试图在同一个context [python.org]中删除这个打开的文件,所以出现了[WinError 32]

你需要先关闭文件,然后立即删除,这样可以确保你仍然是被允许的文件持有者,并且不会违反任何共享政策。[1]

顺便说一下,这也是Windows被称为“伟大”操作系统的众多原因之一。搞笑的是,在基于Unix的操作系统上就没有这种麻烦。


[1] 我曾经遇到过这样的情况,就是在我想再次使用一个文件之前,另一个程序恰好占用了这个文件。这导致了一个让人震惊的bug。

2

权限错误: [WinError 32] 这个进程无法访问文件,因为它正在被另一个进程使用:

这个错误的意思是文件已经打开了,所以不能删除。

出现这个问题是因为你在代码的 with open 代码块里面尝试删除文件。

你应该把这行代码 os.remove(os.path.join(folder_b, filename)) 移到 open 代码块之外。

确保 folder_bfilename 这两个变量在 open 代码块外面也能用。

撰写回答