Search code examples
c#filesystemwatchercopying

C# FileSystemWatcher Copy folder complete


I am using FileSystemWatcher to monitor a folder that will be used to do some file renaming.
The only thing that will be copied will be folders containing files. There will not be single files put into the monitored folder. This is the code for setting up the FileSystemWatcher

watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName;
watcher.IncludeSubdirectories = true;
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.Renamed += new RenamedEventHandler(watcher_Renamed);
watcher.EnableRaisingEvents = true; 

There doesn't seem to be any issues with this setup..

The folders being copied can be between 50-200mb big. Is there a way to check/make sure that all the files have completed copying before starting the renaming process. I tried this thinking that i would get an IOException if the copying was still happening when the GetFiles() was called.

bool finishedCopying = false;
while (!finishedCopying)
{
    try
    {
        List<FileInfo> fileList = directoryInfo.GetFiles().ToList();
        AlbumSearch newAlbum = new AlbumSearch(directoryInfo);
        return newAlbum;
    }
    catch (IOException)
    {
        finishedCopying = false;
    }
}

If anymore information is required, just ask an i can provide.

Ta.


Solution

  • I gave this a go using a timer. It may not be the prettiest solution out there but at first testing it seems to be working so far. Essentially what this does is when a folder is copied to the monitored folder it will add the folder path to the AlbumList. The files in that folder will trigger the Created event. This waits for the file to finish copying. Once finished it starts a timer. If a new Created event gets triggered the timer will reset itself.

    When the timer.elapsed event is triggered it assumes (and I know assumption is the mother of all f*&k ups) that there are no more files to be copied and can start to process the fully copied folder..

    System.Timers.Timer eventTimer = new System.Timers.Timer(); 
    List<string> AlbumList = new List<string>();
    
    private void watcher_Created(object sender, FileSystemEventArgs e)
    {    
        if (Directory.Exists(e.FullPath))
        {
            AlbumList.Add(e.FullPath);
        }
    
        if (File.Exists(e.FullPath))
        {
            eventTimer.Stop();
            FileInfo newTrack = new FileInfo(e.FullPath);
            while (IsFileLocked(newTrack))
            {
                // File is locked. Do Nothing..
            }
            eventTimer.Start();              
        }
    }
    
    private void eventTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        List<string> ItemToRemove = new List<string>();
        foreach (var item in AlbumList)
        {            
            DirectoryInfo di = new DirectoryInfo(item);
            AlbumSearch newAlbum = new AlbumSearch(di);
    
            if (DoSomethingMethod(newAlbum))
            {
                ItemToRemove.Add(item);
            }
            else
            {
                // why did it fail
            }
        }
    
        foreach (var path in ItemToRemove)
        {
            AlbumList.Remove(path);
        }
    }
    
    private bool DoSomethingMethod(AlbumSearch as)
    {
        // Do stuff here 
        return true;
    }