System.IO.DirectoryNotFoundException после удаления пустой папки и ее воссоздания

Я хочу скопировать папку, и сначала хочу удалить папку назначения. Поэтому я удаляю папку назначения, затем создаю ее, а затем копирую файлы. Проблема в том, что я получаю An unhandled exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll при попытке скопировать файлы. Это код

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);
        }.......

Я получаю исключение в этой строке FileInfo fileinfo = new FileInfo(dest);.

Кажется, что есть задержка в создании папки, и в то же время я пытаюсь скопировать файл в нее. Какой-нибудь ключ, в чем проблема? Полное сообщение об ошибке:

Необработанное исключение типа 'System.IO.DirectoryNotFoundException' произошел в mscorlib.dll

Дополнительная информация: Не удалось найти часть пути. 'C:\Users\джо\Desktop\destfolder \.buildpath

Решение

Как отмечали хорошие люди, причиной этого исключения является то, что я пытаюсь воссоздать папку до завершения процесса удаления. Таким образом, решение состоит в том, чтобы добавить 2 строки кода после удаления: GC.Collect(); GC.WaitForPendingFinalizers();

поэтому правильный код будет

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);
    }.......

Таким образом, вы ждете с созданием до тех пор, пока процесс удаления не будет завершен. Yhanks все и особенно Саид.

Ответ 1

У тебя это получилось неправильно. Причиной исключения является то, что все еще есть ресурс, который обращается к папке (или файлу).

Решение никогда не GC.collect() или Sleep()... Это просто работа. То, что вы делаете, это просто позволить сборщику мусора распоряжаться ресурсом, а затем дать ему время действовать.

RIGHT - управлять своими собственными ресурсами. Вместо статического метода, с которым вы не контролируете, используйте блок using и удалите ресурс в конце блока. Таким образом, нет накладных расходов, пока вы ожидаете вещей, которые не находятся под вашим контролем (GC).

Используйте объект, который управляет ресурсами, а блок using будет располагать его в конце.

В вашем случае используется один объект DirectoryInfo, который контролирует этот ресурс.

Ответ 2

Я запутался в вашем текущем решении. GC не имеет ничего общего с удалением папки, она работает только потому, что добавление функций, связанных с GC, похоже на добавление Thread.Sleep() или MessageBox. Он работает только случайно.

Вместо этого вам следует подождать, пока каталог фактически не будет удален, например:

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

Только после завершения этого кода вы должны продолжить.

Ответ 3

Попробуйте вместо этого использовать FileIO-метод, у меня была такая же проблема, код ниже работает отлично.

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

Ответ 4

Почему вы устанавливаете атрибуты файла после копирования файла? Это необходимо?

Что вы можете сделать, так это сначала установить разные атрибуты и затем выполнить фактическую копию файла. Также имеет смысл, сначала проверяя, является ли это файлом ReadOnly, и если это так, установите его в Normal и сделайте копию.

Ответ 5

Извините за ответ и не комментирование, но моя репутация еще недостаточно высока. В MSDN написано, что путь должен быть "хорошо сформированным" http://msdn.microsoft.com/en-gb/library/system.io.fileinfo%28v=VS.90%29.aspx

Может быть, попробуйте, поместив файл в рабочий каталог? Таким образом, путь не требуется, и вы можете увидеть, находится ли проблема в пути или в файле...

Ответ 6

Хорошо Это очень странно. исключение происходит только тогда, когда папка назначения пуста. но добавление следующей строки после удаления папки назначения, похоже, решает проблему. линия: MessageBox.Show(папка "folder" + destFolder + "была удалена", "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);
        }

поэтому размещение MessageBox.show после удаления приведет к исчезновению System.IO.DirectoryNotFoundException. его как будто тот факт, что после удаления происходит небольшая задержка, воссоздание папки идет хорошо. я думаю, я найду работу вокруг этого, но если кто-то знает, что вызывает это и способ его решения, я буду очень рад его услышать.

Ответ 7

Сначала попробуйте установить Fileinfo из dest, затем скопируйте

    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);

    }.......