Как скопировать папку целиком и все файлы и папки в ней

516
17 апреля 2017, 02:36

Собственно сабж)

Нарыскал пример:

void CopyDir(string FromDir, string ToDir)
{
   Directory.CreateDirectory(ToDir);
   foreach (string s1 in Directory.GetFiles(FromDir))
   {
      string s2 = ToDir + "\\" + Path.GetFileName(s1);
      File.Copy(s1,s2);
   }
   foreach (string s in Directory.GetDirectories(FromDir))
   {
      CopyDir(s, ToDir + "\\" + Path.GetFileName(s));
   }
}

Есть ли методы по серьёзнее?

Answer 1

Времена однозадачных одно-пользовательских ОС ушли, во всяком случае на PC. Там можно было позволить себе не проверять права на файлы и не бояться. что после проверки на наличие, файла (вдруг!) не окажется при чтении. Но и там были проблемы, которые нужно было решать, например ошибки чтения на аппаратном уровне.

Файловая система штука нестабильная. Может произойти что угодно, от отключения электричества, до изменения прав вредным админом прямо во время работы вашей программы. И это нужно учитывать.

Копирование дерева папок, как базовый алгоритм не представляет сложностей, классический рекурсивный обход в глубину или ширину, на усмотрение автора. В самом вопросе и соседнем ответе их приведено несколько. Но в многопользовательской многозадачной среде придется учитывать особенности этой среды на каждом этапе алгоритма.

1. Обязательная обработка исключений.

Файловые операции могут генерировать (и генерируют) массу различных исключений (исключения File.Open). По хорошему, каждый тип исключений нужно обрабатывать в отдельном блоке catch, почему см. ниже.

2. Копирование папки операция комплексная и долгая

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

  • на n-ном шаге операции произошло исключение: игнорировать, прервать операцию, спросить у пользователя?
  • как было сказано выше, исключения бывают разные, соответственно как будем реагировать на конкретные типы исключений?
  • что делать с уже обработанными объектами прерванной операции: удалить, оставить как есть?
  • если удалить, то как быть с замещенными файлами? Да да, должен быть бекап или теневая копия, или CVS, или что там еще можно придумать. а если их нет?

И это я еще не упомянул возможное отключение носителя нерадивым пользователем во время копирования, битые кластеры, электрика с рубильником, соседа сварщика, погоду на Венере и еще много чего, что так или иначе может спровоцировать исключение.

3. Серебряной пули нет

На все перечисленные и не перечисленные вопросы придется отвечать при любых операциях с файлами, в некоторых случаях ответы простые, в некоторых нет. Универсального решения тут нет. Где-то нужна надежность, где-то целостность данных, где-то скорость, а где-то отсутствие надоедливых вопросов пользователю. Цели разные, решения тоже.

Общая рекомендация может быть следующей:

  • не бойтесь исключений при работе с файловой системой, они есть и ими нужно правильно пользоваться. Для маньяков жадных до скорости и производительности - операции с объектами файловой системы на любом из современных носителей, включая RAM-диски, выполняются медленнее генерации и обработки исключений. Не экономьте на спичках.
  • забудьте про File.Exists, он не помощник в современном окружении, если конечно вашей целью является что-то кроме самой проверки на существование файла/папки.
  • оборачивайте в try catch finaly все операции с объектами файловой системы.
  • предусмотрите корректное завершение операции, прерванной исключением, если это возможно.
  • если логика программы позволяет, то оповещайте пользователя о проблемах сразу, не обязательно навязчиво, можно просто выводом в консоль или лог, если от пользователя не требуется решение, или более настойчиво, если без его активного вмешательства не обойтись.
  • если операция может повредить данные (перезапись, удаление и т.д.) переспросите пользователя в его уверенности. Да пользователи будут материться (я тоже, да да =)), но у вас и у пользователя будет хотя бы небольшая уверенность в том, что это действие выполнил именно он, а не его кот или 3-х летний ребенок.
Answer 2

Вариант 1:

//Создать идентичную структуру папок
foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", 
    SearchOption.AllDirectories))
{
    try
    {
        Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));
    }
    catch(Exception e)
    {
         //здесь обрабатывай ошибки
    }
}
//Копировать все файлы и перезаписать файлы с идентичным именем
foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", 
    SearchOption.AllDirectories))
{
    try
    {
        File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);
    }
    catch(Exception e)
    {
         //здесь обрабатывай ошибки
    }
}

Вариант 2

Process proc = new Process();
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = @"C:\WINDOWS\system32\xcopy.exe";
proc.StartInfo.Arguments = $"{SourcePath} {DestinationPath} /E /I";
// /E = скопировать подпапки(пустые в том числе!).
// /I = если дестинейшн не существует, создать папку с нужным именем. 
proc.Start();

Вариант 3:

добавь референс на библиотеку Visual Basic и воспользуйся методом:

Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(fromDirectory, toDirectory);

Все ответы взяты при гуглении с: http://stackoverflow.com/questions/58744/copy-the-entire-contents-of-a-directory-in-c-sharp и немного изменены/добавлены коментарии

READ ALSO
C# Получение значения из List

C# Получение значения из List

Привет, друзьяНадеюсь Вы мне поможете, потому что я только начинающий в C#

252
Добавление записи в бд через DropDownList ASP.NET

Добавление записи в бд через DropDownList ASP.NET

вот код Service_type поле в которое нужно записать, Type собственно сам айдишник dropdownlist-аЧто не так с моим кодом?

278
Конвертировать Json в Xml

Конвертировать Json в Xml

Имеется ссылка, отображающая json код, после ее получения, мне необходимо конвертировать в XML формат

340
TreeNodeView в ASP.NET, не могу вывести всю иерархию

TreeNodeView в ASP.NET, не могу вывести всю иерархию

Всем привет! Я новичок в C# и APSNET

212