使用文件观察程序删除文件,不允许我第二次删除

本文关键字:删除 文件 第二次 不允许 允许我 程序 观察 | 更新日期: 2023-09-27 18:27:15

我的任务是在处理完成后删除文件。我正在使用FileWatcher来完成此任务。它正在监视特定的文件夹。假设我复制了一个文件,并把它放在filewatcher文件夹中,它正在删除。第二次,当我复制相同的文件并将其粘贴到相同的观察文件夹中时。这一次它说另一个进程正在使用该文件。例外是抛出。我想我错过了什么。这是我的代码

private static void Main(string[] args)
    {
       var fw = new FileSystemWatcher(EmailSetting.DataFolder)
        {
            IncludeSubdirectories = false
            ,
            EnableRaisingEvents = true
        };
        fw.Created += (sender, e) =>
        {
         File.Delete(e.FullPath);
        };
        Console.ReadLine();
    }

使用文件观察程序删除文件,不允许我第二次删除

创建文件时会收到Created事件(因此得名)。但在这个时候,实际创建它的另一个过程并没有完成将内容写入该文件。因此,该文件可能已经存在,但另一个文件仍在处理中(假设您要复制一个8GB的文件)。

更明智的做法是简单地将文件的路径写入事件中的列表,并让另一个线程定期检查这个并发包(例如,每秒一次)。首先,它会检查文件是否存在,如果存在,请尝试删除它。如果成功,请将其从包中删除,否则下次重试。

代码示例

private static readonly ConcurrentQueue<FileInfo> _FileCandidates = new ConcurrentQueue<FileInfo>();
private static void Main(string[] args)
{
    var watcher = new FileSystemWatcher
    {
        Path = @"R:'TestFolder",
        IncludeSubdirectories = false,
        Filter = "*.*",
    };
    Console.WriteLine("Start watching folder... " + watcher.Path);
    watcher.Created += OnFileCreated;
    watcher.EnableRaisingEvents = true;
    var timer = new Timer
    {
        AutoReset = true,
        Interval = 1000,
    };
    timer.Elapsed += OnTimerElapsed;
    timer.Enabled = true;
    Console.ReadKey();
}
static void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
    FileInfo file;
    var stillInUseFiles = new List<FileInfo>();
    Console.WriteLine("Check for file candidates...");
    while (_FileCandidates.TryDequeue(out file))
    {
        try
        {
            Console.WriteLine("Delete " + file.FullName);
            if (file.Exists)
                file.Delete();
        }
        catch (IOException)
        {
            Console.WriteLine("Could not delete file, try again next time.");
            stillInUseFiles.Add(file);
        }
    }
    foreach (var unhappyFile in stillInUseFiles)
    {
        _FileCandidates.Enqueue(unhappyFile);
    }
}
static void OnFileCreated(object sender, FileSystemEventArgs e)
{
    Console.WriteLine("Found new file candidate " + e.FullPath);
    _FileCandidates.Enqueue(new FileInfo(e.FullPath));
}