Как рекурсивно перечислить все файлы в каталоге на C # и скопировать все файлы в другой каталог

#image #indexing #directory #recursive-query

#изображение #индексирование #каталог #рекурсивный запрос

Вопрос:

Я пытаюсь написать консольное приложение на c #, которое рекурсивно считывает определенную папку. В этих папках находятся тысячи изображений в формате .jpg

Структура папок очень глубока на некоторых уровнях, и пример выглядит следующим образом:

Scc-LocalPhoto/testfiles /1997 / ЯНВАРЬ-июнь 1997 / АПРЕЛЬ 1997/7.4.97 — 11.4.97 / FRI11.4.97/

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

Моя задача — прочитать все папки. Извлеките метаданные из изображений и сохраните в XML-файле. Затем мне нужно скопировать все папки в том же формате и вставить их в новую папку.

Я думаю, что смогу прочитать все каталоги и извлечь метаданные из изображений и сохранить их в XML-файле.

Чего я не знаю, как сделать, так это скопировать все папки и изображения и вставить их в новый каталог, сохраняя ту же структуру папок.

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

Я довольно новичок в C # и пишу консольные приложения. Спасибо за ваше время.

Ответ №1:

Рекурсивный анализ каталогов

 static void ParseDirectories(string root)
{
    ProcessDirectory(new DirectoryInfo(root));

    string[] subDirectories = Directory.GetDirectories(root);

    // No more directories to explore
    if (subDirectories.Length == 0)
        return;

    foreach (string subDirectory in subDirectories)
    {
        ParseDirectories(subDirectory);
    }
}
  

Обработка файлов в каталоге

 static void ProcessDirectory(DirectoryInfo directory)
{
    foreach (FileInfo file in directory.EnumerateFiles("*.jpg")
    {
        // record metadata and do other work on each file here
    }
}
  

Копирование дерева каталогов

 static void CopyDirectoryTree(DirectoryInfo source, DirectoryInfo dest)
{
    if (!Directory.Exists(dest.FullName))
        Directory.CreateDirectory(dest.FullName);

    bool overwrite = true;

    // Copy files
    foreach (FileInfo file in source.EnumerateFiles())
    {
        file.CopyTo(Path.Combine(dest.ToString(), file.Name), overwrite);
    }

    // Copy Sub-directories
    foreach (DirectoryInfo subDirectory in source.GetDirectories())
    {
        DirectoryInfo newDirectory = destination.CreateSubdirectory(subDirectory.Name);
        CopyDirectoryTree(subDirectory, newDirectory);
    }
}
  

Пример использования

 static void Main(string[] args)
{
    // Process each directory
    string initialDirectory = @"C:path_to_folder";
    ParseDirectories(initialDirectory);

    // Copy directory tree
    string destinationDirectory = @"C:path_to_new_root_directory";
    CopyDirectoryTree(
        new DirectoryInfo(initialDirectory),
        new DirectoryInfo(destinationDirectory));
}
  

Надеюсь, это поможет!

Комментарии:

1. @Jason Тебе повезло с этим?

2. Этот код отлично работает. Спасибо aligray. Приношу свои извинения за задержку с ответом вам. Спасибо за ваше время и помощь. С благодарностью.

Ответ №2:

Могу ли я предложить следующее, которое, на мой взгляд, немного более простое

 public static void CopyFolderTree(string sourcePath, string targetPath)
{
    var sourceDir = new DirectoryInfo(sourcePath);
    var targetDir = new DirectoryInfo(targetPath);

    targetDir.Create();

    foreach(var file in sourceDir.GetFiles())
        file.CopyTo(Path.Combine(targetPath, file.Name), true);

    foreach(var subfolder in sourceDir.GetDirectories())
        CopyFolderTree(subfolder.FullName, Path.Combine(targetPath, subfolder.Name));
}