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

僤鯓⒐⒋嵵緔 提交于 2019-12-04 16:34:41

问题


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.


回答1:


You got it kinda wrong. The reason for the exception is that there's still a resource that is accessing the folder (or file).

The solution is never GC.collect() or Sleep()... That's just a work around. What you're doing is just letting the garbage collector dispose of the resource, and then giving it time to act.

The RIGHT way is to manage your own resources. Instead of a static method that you have no control on, use a using block and dispose of the resource in the end of the block. This way there's no overhead while your waiting for things that aren't under your control (GC).

Use an object that controls the resources, and the using block will dispose it at the end.

In your case, using a single DirectoryInfo object that controls that resource should work.




回答2:


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.




回答3:


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

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




回答4:


Why are you setting the file attributes after you have copied the file? Is this necessary?

What you could do is first setting the the different attributes and afterwards doing the actual file copy. It also makes more sense, first checking if it is a ReadOnly file, and if it is, then set it to Normal, and do the copy.




回答5:


Sorry for answering and not commenting but my reputation isn't high enought yet. In the MSDN is written, that the path has to be "well-formed" http://msdn.microsoft.com/en-gb/library/system.io.fileinfo%28v=VS.90%29.aspx

Maybe trying it out, by putting file in the working directory? So no path is needed and you can see if the problem is in the path or in the file...




回答6:


Ok This is very strange. the exception only happen when the destination folder is empty. but adding the folowing line after the destination folder deletion seem to solve the problem. the line : MessageBox.Show("folder " + destFolder + "folder was deleted", "alert");

static public void CopyFolder(string sourceFolder, string destFolder)
    {
        if (Directory.Exists(destFolder)) // check if folder exist
        {
            Directory.Delete(destFolder, true);  // delete folder
            MessageBox.Show("folder " + destFolder + "folder was deleted", "alert");
        }
        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);
        }

so putting a MessageBox.show after the deletion causes the System.IO.DirectoryNotFoundException to go away. its as if the fact that there is a small delay after the deletion , the recreation of the folder goes well. i guess i will find a work around this, but if someone knows what is causing this and the way to solve it , i will be very happy to hear it.




回答7:


Try to set Fileinfo of dest first, then copy

    foreach (string file in files)
    {
        string name = Path.GetFileName(file);
        string dest = Path.Combine(destFolder, name);

        FileInfo fileinfo = new FileInfo(dest); // get file attrib
        dest.Attributes = FileAttributes.Normal;
        File.Copy(file, dest, true);

    }.......


来源:https://stackoverflow.com/questions/4216396/system-io-directorynotfoundexception-after-deleting-an-empty-folder-and-recreati

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!