C # move file as soon as available

I need to complete the following task:

An attempt was made to move a file. If the file is locked, schedule to move as soon as it becomes available.

I am using File.Move which is sufficient for my program. Now the problems are as follows:

1) I cannot find a good way to check if the file I need to move is locked. I am breaking System.IO.IOException, but while reading other posts, I found that the same exception can be thrown for different reasons.

2) Determining when the file is unlocked. One way to do this is probably using a timer / thread, and checking the scheduled files lets you speak every 30 seconds and try to move them. But I hope it's better to use FileSystemWatcher.

This is a winnet 3.5 application. Any comments / suggestions are appreciated. Thank you for attention.

+2


a source to share


6 answers


You should really just try to catch the IOException. Use Marshal.GetHRForException to check the reason for the exception. The notification will not be reliable. Another process might lock the file again before File.Move is executed.



+4


a source


It's simple:



        static void Main(string[] args)
        {
            //* Create Watcher object.
            FileSystemWatcher watcher = new FileSystemWatcher(@"C:\MyFolder\");

            //* Assign event handler. 
            watcher.Created += new FileSystemEventHandler(watcher_Created);

            //* Start watching. 
            watcher.EnableRaisingEvents = true;

            Console.ReadLine();
        }


        static void watcher_Created(object sender, FileSystemEventArgs e)
        {
            try
            {
                File.Move(e.FullPath, @"C:\MyMovedFolder\" + e.Name);
            }
            catch (Exception)
            {
                //* Something went wrong. You can do additional proceesing here, like fire-up new thread for retry move procedure.
            }
        }

      

+2


a source


One possible alternative is to use it MoveFileEx

with a flag MOVEFILE_DELAY_UNTIL_REBOOT

. If you don't have access to move the file right now, you can schedule it to move on the next reboot when it is guaranteed to be available (the move happens very early in the download sequence).

Depending on your specific application, you can inform the user to reboot and initiate the reboot yourself, in addition to the moving schedule.

+1


a source


This is not relevant to your problem, but usually you always need to keep the "try and gracefully fail" mode of operation for this kind of action.

This is because, despite the clever mechanism for detecting your file, there will always be some amount of time between the time you discover that the file is available and move it, at which time someone might mess up the file.

+1


a source


Scheduled repetition on an exception (probably increasing latency - up to a point) is probably the easiest way to achieve this (your (2)). To do this correctly, you will need to go to the system level (with kernel code) to capture the file close event, which has its own idiosynchronous timing. This is a lot of work — orders of magnitude more difficult than the planned retry method. It is up to you and your application to make this call, but I don't know of anything effective in between.

+1


a source


Take a look at FileSystemWatcher.

http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(VS.90).aspx

Listens for file system change notifications and raises events when a directory or file in a directory changes

0


a source







All Articles