System.IO.DirectoryNotFoundException после удаления пустой папки и ее повторного создания - PullRequest
13 голосов
/ 18 ноября 2010

Я хочу скопировать папку и сначала хочу удалить папку назначения.Поэтому я удаляю папку назначения, затем воссоздаю ее и затем копирую файлы.Проблема в том, что я получаю 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 \ joe \ 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);
    }.......

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

Ответы [ 7 ]

4 голосов
/ 22 ноября 2010

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

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

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

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

1 голос
/ 21 октября 2011

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

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

0 голосов
/ 13 января 2011

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

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

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

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

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

0 голосов
/ 19 ноября 2010

Попробуйте сначала установить 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);

    }.......
0 голосов
/ 18 ноября 2010

Хорошо. Это очень странно.Исключение происходит только тогда, когда папка назначения пуста.но добавление следующей строки после удаления папки назначения, похоже, решает проблему.строка: MessageBox.Show («папка» + destFolder + «папка была удалена», «оповещение»);

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уходи.Как будто тот факт, что после удаления происходит небольшая задержка, восстановление папки проходит хорошо.я думаю, что найду работу вокруг этого, но если кто-то знает, что вызывает это и способ решить это, я буду очень рад услышать это.

0 голосов
/ 18 ноября 2010

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

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

0 голосов
/ 18 ноября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...