Chandrahas Balleda
Chandrahas Balleda

Reputation: 2822

The process cannot access the file because it is being used by another process - Filewatcher - C# - Console Application

I was trying to detect a file in a folder using Filewatcher and move the file to a new location. While doing so using a console application, I am getting error as The process cannot access the file because it is being used by another process.

I am getting this error at File.Move(f.FullName, System.IO.Path.Combine(@"C:\Users\ADMIN\Downloads\FW_Dest", Path.GetFileName(f.FullName))); in the OnChanged method. Please check the below code and help me with this issue. Thanks in advance.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Permissions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Run();

        }

        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]

        public static void Run()
        {


            FileSystemWatcher watcher = new FileSystemWatcher(); 
            watcher.Path = @"C:\Users\ADMIN\Downloads\FW_Source";
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
           | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Filter = "*.*";

            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;

            Console.WriteLine("Press \'q\' to quit the sample.");
            while (Console.Read() != 'q') ;
        }


        private static void OnChanged(object source, FileSystemEventArgs e)
        {

            DirectoryInfo directory = new DirectoryInfo(@"C:\Users\ADMIN\Downloads\FW_Source\");
            FileInfo[] files = directory.GetFiles("*.*");
            foreach (var f in files)
            {
                File.Move(f.FullName, System.IO.Path.Combine(@"C:\Users\ADMIN\Downloads\FW_Dest", Path.GetFileName(f.FullName)));
            }

        }


    }
}

Upvotes: 0

Views: 4354

Answers (3)

Andrew
Andrew

Reputation: 123

I ran into this problem with larger files being moved into the watched folders.

I called the IsLocked method in my OnChange method and don't move past it till it returns false.

while (IsFileLocked(ImportFormat.FileName)) {
    //Do nothing until the file is finished writing
}

IsLocked Method:

/// <summary>
///     Tries to open the file for R/W to see if its lock. Returns Boolean
/// </summary>
/// <param name="filePath"></param>
/// <returns>bool</returns>
protected static bool IsFileLocked(string filePath) {
    FileStream stream = null;
    var file = new FileInfo(filePath);
    try {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }catch (IOException err) {
        //the file is unavailable because it is:
        //still being written to
        //or being processed by another thread
        //or does not exist (has already been processed)
        return true;
    } finally {
        stream?.Close();
    }

    //file is not locked
    return false;
}

Upvotes: 0

Patrick McDonald
Patrick McDonald

Reputation: 65421

Instead of moving all the files in the watched folder, just move the file which was created, like so:

private static void OnChanged(object source, FileSystemEventArgs e)
{
    File.Move(e.FullPath, Path.Combine(@"C:\Users\ADMIN\Downloads\FW_Dest", e.Name));
}

A better way than Thread.Sleep(2000) to wait 2 seconds would be as follows:

private static async void OnChanged(object source, FileSystemEventArgs e)
{
    await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);

    File.Move(e.FullPath, Path.Combine(targetFolder, e.Name));
}

This would prevent the program from locking multiple threads if many files are copied in sinultaneously.

Upvotes: 2

zmbq
zmbq

Reputation: 39013

You're getting the Changed event while the file is being changed. You're trying to move it before the process writing to the file is done. I

suggest you first try to open the file exclusively (deny read, deny write), and only when you succeed close it and move the file. If you don't succeed, wait a few seconds and try again.

Upvotes: 6

Related Questions