Try this:
Method to get files by mask (.Net 4.0+):
public static IEnumerable<string> GetFiles(string path, string searchPatternExpression = "", SearchOption searchOption = SearchOption.AllDirectories) { Regex reSearchPattern = new Regex(searchPatternExpression); //Здесь searchPatternExpression - это регулярное выражение для поиска файлов, например, \.mp3|\.mp4|\.doc или оставьте пустым для любых файлов. return Directory.EnumerateFiles(path, "*", searchOption).Where(file => reSearchPattern.IsMatch(Path.GetFileName(file))); }
If you are not 4.0, but lower, then here is a similar method for .NET 3.5:
public static string[] GetFilesNET35(string path, string searchPatternExpression, SearchOption searchOption) { if (searchPatternExpression == null) searchPatternExpression = string.Empty; Regex reSearchPattern = new Regex(searchPatternExpression); return Directory.GetFiles(path, "*", searchOption).Where(file => reSearchPattern.IsMatch(Path.GetFileName(file))).ToArray(); }
If, for example, we want to transfer all folders and files from the C: \ App \ Test \ Path directory to D: \ NewPath, then we still need the following method:
public static string GetRelativeFileName(string BasePath, string FullPath) { if (FullPath.StartsWith(BasePath)) { BasePath = BasePath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; return FullPath.Replace(BasePath, string.Empty); } return string.Empty; }
Now in the loop we copy ALL files (for not all, but for choice if - set the mask for GetFiles ):
... //Переменная для создания новых папок string newDir = string.Empty; string basePath = "Папка-источник"; string newPath = "Целевая папка"; //Переменная для короткого относительного имени файла (путь относительно базовой папки) string shortFilename = string.Empty; //Переменная для формирования нового имени файла string newFilename = string.Empty; //Делаем так, что бы наш новый путь всегда заканчивался на \ (обратный слэш) newPath = newPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; //Получаем список файлов: var files = GetFiles("Корневой путь для начала сканирования"); //Обходим полученный список и копируем файлы и папки из базовой в целевую папку: foreach (var file in files) { //Вычисляем разницу между текущим и новым путём shortFilename = UT.GetRelativeFileName(basePath, file); //Задаем новый полный путь, куда будет скопирован файл newFilename = newPath + shortFilename; //И узнаем папку, куда этот файл нужно положить будет newDir = Path.GetDirectoryName(newFilename); //Если такой папки нет - создаем её: if (!Directory.Exists(newDir)) { try { //Создание папки и всех сопутствующих папок: Directory.CreateDirectory(path); } catch (Exception ex) { throw ex; } } try { //Копируем старый файлик на новое место с замещением уже существующих (если вдруг там уже есть с таким именем файл) File.Copy(file, newFilename, true); } catch (Exception e) { throw e; } }
It seems everything, just do not forget to handle the errors properly , and not just throw exceptions, as in my example. You have already, for example, spoken in the comments about the possibility of errors associated with access rights.
I copied the code from a working real application, slightly cleaning it up and simplifying it (just deleted the specific error handling and logging). Should work if nothing messed up.