Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.IO.File.Move--How to wait for move completion?

Tags:

c#

wpf

I am writing a WPF application in c# and I need to move some files--the rub is that I really REALLY need to know if the files make it. To do this, I wrote a check that makes sure that the file gets to the target directory after the move--the problem is that sometimes I get to the check before the file finishes moving:

   System.IO.File.Move(file.FullName, endLocationWithFile);

            System.IO.FileInfo[] filesInDirectory = endLocation.GetFiles();
            foreach (System.IO.FileInfo temp in filesInDirectory)
            {
                if (temp.Name == shortFileName)
                {

                    return true;
                }
            }

            // The file we sent over has not gotten to the correct   directory....something went wrong!
            throw new IOException("File did not reach destination");

        }
        catch (Exception e)
        {
            //Something went wrong, return a fail;
            logger.writeErrorLog(e);
            return false;
        }

Could somebody tell me how to make sure that the file actually gets to the destination?--The files that I will be moving could be VERY large--(Full HD mp4 files of up to 2 hours)

Thanks!

like image 965
Mizmor Avatar asked Jan 04 '13 18:01

Mizmor


2 Answers

You could use streams with Aysnc Await to ensure the file is completely copied

Something like this should work:

private void Button_Click(object sender, RoutedEventArgs e)
{
    string sourceFile = @"\\HOMESERVER\Development Backup\Software\Microsoft\en_expression_studio_4_premium_x86_dvd_537029.iso";
    string destinationFile = "G:\\en_expression_studio_4_premium_x86_dvd_537029.iso";

    MoveFile(sourceFile, destinationFile);
}

private async void MoveFile(string sourceFile, string destinationFile)
{
    try
    {
        using (FileStream sourceStream = File.Open(sourceFile, FileMode.Open))
        {
            using (FileStream destinationStream = File.Create(destinationFile))
            {
                await sourceStream.CopyToAsync(destinationStream);
                if (MessageBox.Show("I made it in one piece :), would you like to delete me from the original file?", "Done", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    sourceStream.Close();
                    File.Delete(sourceFile);
                }
            }
        }
    }
    catch (IOException ioex)
    {
        MessageBox.Show("An IOException occured during move, " + ioex.Message);
    }
    catch (Exception ex)
    {
        MessageBox.Show("An Exception occured during move, " + ex.Message);
    }
}

If your using VS2010 you will have to install Async CTP to use the new Async/Await syntax

like image 66
sa_ddam213 Avatar answered Oct 03 '22 00:10

sa_ddam213


You could watch for the files to disappear from the original directory, and then confirm that they indeed appeared in the target directory.

I have not had great experience with file watchers. I would probably have the thread doing the move wait for an AutoResetEvent while a separate thread or timer runs to periodically check for the files to disappear from the original location, check that they are in the new location, and perhaps (depending on your environment and needs) perform a consistency check (e.g. MD5 check) of the files. Once those conditions are satisfied, the "checker" thread/timer would trigger the AutoResetEvent so that the original thread can progress.

Include some "this is taking way too long" logic in the "checker".

like image 43
Eric J. Avatar answered Oct 03 '22 00:10

Eric J.