Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.IO.DirectoryNotFoundException after deleting an empty folder and recreating it

I want to copy a folder, and i want to delete destination folder first. So I am deleting destination folder then recreate it and then copy files. The problem is that i get the An unhandled exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll when trying to copy files. This is the code

static public void CopyFolder(string sourceFolder, string destFolder)
    {
        if (Directory.Exists(destFolder)) // check if folde exist
        {
            Directory.Delete(destFolder, true);  // delete folder
        }
        Directory.CreateDirectory(destFolder); // create folder

        string[] files = Directory.GetFiles(sourceFolder);
        foreach (string file in files)
        {
            string name = Path.GetFileName(file);
            string dest = Path.Combine(destFolder, name);
            File.Copy(file, dest, true);
            FileInfo fileinfo = new FileInfo(dest); // get file attrib
            if (fileinfo.Attributes != FileAttributes.ReadOnly) // check if read only 
                File.SetAttributes(dest, FileAttributes.Normal);
        }.......

I get the exception in this line FileInfo fileinfo = new FileInfo(dest);.

It seems like there is a delay in the creation of the folder and in the mean time I try to copy a file into it. Any clue, what is the problem? The full exception message:

An unhandled exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll

Additional information: Could not find a part of the path 'C:\Users\joe\Desktop\destfolder\.buildpath'.

SOLUTION

As it been pointed out by good people, the reason for this exception is that I try recreating the folder before the deletion process is finished. So the solution is to add 2 lines of code after deletion: GC.Collect(); GC.WaitForPendingFinalizers();

so the correct code will be

static public void CopyFolder(string sourceFolder, string destFolder)
{
    if (Directory.Exists(destFolder)) // check if folde exist
    {
        Directory.Delete(destFolder, true);  // delete folder
        GC.Collect();    // CODE ADDED
        GC.WaitForPendingFinalizers(); // CODE ADDED
    }
    Directory.CreateDirectory(destFolder); // create folder

    string[] files = Directory.GetFiles(sourceFolder);
    foreach (string file in files)
    {
        string name = Path.GetFileName(file);
        string dest = Path.Combine(destFolder, name);
        File.Copy(file, dest, true);
        FileInfo fileinfo = new FileInfo(dest); // get file attrib
        if (fileinfo.Attributes != FileAttributes.ReadOnly) // check if read only 
            File.SetAttributes(dest, FileAttributes.Normal);
    }.......

This way, you wait with the creation until the deletion process is finished. Yhanks everyone and especially Saeed.

like image 514
yossi Avatar asked Nov 18 '10 15:11

yossi


2 Answers

I am confused about your current solution. GC has nothing to do with deleting a folder, it only works because adding GC related functionality there is similar to adding Thread.Sleep() or a MessageBox. It works only by chance.

Instead, you should wait until the directory is actually deleted, e.g:

Directory.Delete(destFolder, true);  // delete folder
while(Directory.Exists(destFolder))
{
Thread.Sleep(100);
}

Only once this code finishes, you should continue.

like image 91
VitalyB Avatar answered Nov 17 '22 13:11

VitalyB


Try using the FileIO method instead, I had the same issue, code below works perfect.

FileIO.FileSystem.DeleteDirectory(directoryName,FileIO.DeleteDirectoryOption.DeleteAllContent)

like image 20
user1006857 Avatar answered Nov 17 '22 14:11

user1006857