Скопируйте все содержимое каталога в C #

Невозможно, чего вы хотите достичь. Объяснение приведено в справочной документации Spring .

488
задан Keith 16 July 2018 в 07:30
поделиться

7 ответов

Извините за предыдущий код это все еще имело ошибки: ((стал жертвой самой быстрой проблемы оружия). Здесь это тестируется и работа. Ключом является SearchOption. AllDirectories, который избавляет от необходимости явную рекурсию.

string path = "C:\\a";
string[] dirs = Directory.GetDirectories(path, "*.*", SearchOption.AllDirectories);
string newpath = "C:\\x";
try
{
    Directory.CreateDirectory(newpath);
}
catch (IOException ex)
{
    Console.WriteLine(ex.Message);
}
for (int j = 0; j < dirs.Length; j++)
{
    try
    {
        Directory.CreateDirectory(dirs[j].Replace(path, newpath));
    }
    catch (IOException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
for (int j = 0; j < files.Length; j++)            
{
    try
    {
        File.Copy(files[j], files[j].Replace(path, newpath));
    }
    catch (IOException ex)
    {
        Console.WriteLine(ex.Message);
    }
}
1
ответ дан Vinko Vrsalovic 16 July 2018 в 07:30
поделиться

Попробуйте это:

Process proc = new Process();
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "xcopy.exe");
proc.StartInfo.Arguments = @"C:\source C:\destination /E /I";
proc.Start();

Ваши аргументы xcopy могут варьироваться, но Вы получаете идею.

49
ответ дан Jim G. 16 July 2018 в 07:30
поделиться

Хм, я думаю, что неправильно понимаю вопрос, но я собираюсь рискнуть им. Что случилось со следующим простым методом?

public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) {
    foreach (DirectoryInfo dir in source.GetDirectories())
        CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
    foreach (FileInfo file in source.GetFiles())
        file.CopyTo(Path.Combine(target.FullName, file.Name));
}

РЕДАКТИРОВАНИЕ Начиная с этой регистрации собрало впечатляющее количество downvotes для такого простого ответа на одинаково простой вопрос, позвольте мне добавить объяснение. читает это перед downvoting.

, В первую очередь, этот код не является intendend как общедоступной заменой к коду в вопросе. Это для цели иллюстрации только.

Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory делает некоторые дополнительные тесты правильности (например, является ли источник и цель действительными каталогами, является ли источник родителем цели и т.д.), которые отсутствуют в этом ответе. Тот код, вероятно, также более оптимизирован.

Однако код работы хорошо . Это имеет (почти тождественно) используемый в зрелом программном обеспечении в течение многих лет. Кроме свойственной переменчивости дарят все обработки IO (например, что происходит, если пользователь вручную отключает Карту памяти, в то время как Ваш код пишет в него?), нет никаких известных проблем.

, В частности, I’d нравится указывать, что использование рекурсии здесь является абсолютно не проблемой. Ни один в теории (концептуально, it’s самое изящное решение), ни на практике: этот код не переполнит стека . Стек является достаточно большим для обработки даже глубоко вложенных файловых иерархий. Задолго до того, как стековое пространство становится проблемой, ограничение длины пути к папке умирает.

Уведомление, что злонамеренный пользователь мог бы быть в состоянии повредить это предположение при помощи глубоко вложенных каталогов одной буквы каждый. Я haven’t попробовал это. Но только проиллюстрировать тезис: чтобы заставить этот код переполниться на типичном компьютере, каталоги должны были бы быть вложены некоторые тысяча времена. Это - просто не реалистический сценарий.

216
ответ дан Konrad Rudolph 16 July 2018 в 07:30
поделиться

Или, если Вы хотите пойти твердым путем, добавьте ссылку на свой проект для Microsoft. VisualBasic и затем используют следующее:

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

Однако использование одной из рекурсивных функций является лучшим способом пойти, так как это не должно будет загружать VB dll.

42
ответ дан Josef 16 July 2018 в 07:30
поделиться

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

using System;
using System.Runtime.InteropServices;

namespace MyNameSpace
{
    public class ShellFileOperation
    {
        private static String StringArrayToMultiString(String[] stringArray)
        {
            String multiString = "";

            if (stringArray == null)
                return "";

            for (int i=0 ; i<stringArray.Length ; i++)
                multiString += stringArray[i] + '\0';

            multiString += '\0';

            return multiString;
        }

        public static bool Copy(string source, string dest)
        {
            return Copy(new String[] { source }, new String[] { dest });
        }

        public static bool Copy(String[] source, String[] dest)
        {
            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();

            FileOpStruct.hwnd = IntPtr.Zero;
            FileOpStruct.wFunc = (uint)Win32.FO_COPY;

            String multiSource = StringArrayToMultiString(source);
            String multiDest = StringArrayToMultiString(dest);
            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);
            FileOpStruct.pTo = Marshal.StringToHGlobalUni(multiDest);

            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION;
            FileOpStruct.lpszProgressTitle = "";
            FileOpStruct.fAnyOperationsAborted = 0;
            FileOpStruct.hNameMappings = IntPtr.Zero;

            int retval = Win32.SHFileOperation(ref FileOpStruct);

            if(retval != 0) return false;
            return true;
        }

        public static bool Move(string source, string dest)
        {
            return Move(new String[] { source }, new String[] { dest });
        }

        public static bool Delete(string file)
        {
            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();

            FileOpStruct.hwnd = IntPtr.Zero;
            FileOpStruct.wFunc = (uint)Win32.FO_DELETE;

            String multiSource = StringArrayToMultiString(new string[] { file });
            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);
            FileOpStruct.pTo =  IntPtr.Zero;

            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_SILENT | (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION | (ushort)Win32.ShellFileOperationFlags.FOF_NOERRORUI | (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMMKDIR;
            FileOpStruct.lpszProgressTitle = "";
            FileOpStruct.fAnyOperationsAborted = 0;
            FileOpStruct.hNameMappings = IntPtr.Zero;

            int retval = Win32.SHFileOperation(ref FileOpStruct);

            if(retval != 0) return false;
            return true;
        }

        public static bool Move(String[] source, String[] dest)
        {
            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();

            FileOpStruct.hwnd = IntPtr.Zero;
            FileOpStruct.wFunc = (uint)Win32.FO_MOVE;

            String multiSource = StringArrayToMultiString(source);
            String multiDest = StringArrayToMultiString(dest);
            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);
            FileOpStruct.pTo = Marshal.StringToHGlobalUni(multiDest);

            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION;
            FileOpStruct.lpszProgressTitle = "";
            FileOpStruct.fAnyOperationsAborted = 0;
            FileOpStruct.hNameMappings = IntPtr.Zero;

            int retval = Win32.SHFileOperation(ref FileOpStruct);

            if(retval != 0) return false;
            return true;
        }
    }
}
5
ответ дан 16 July 2018 в 07:30
поделиться

Скопированный с MSDN:

using System;
using System.IO;

class CopyDir
{
    public static void Copy(string sourceDirectory, string targetDirectory)
    {
        DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
        DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);

        CopyAll(diSource, diTarget);
    }

    public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
    {
        Directory.CreateDirectory(target.FullName);

        // Copy each file into the new directory.
        foreach (FileInfo fi in source.GetFiles())
        {
            Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name);
            fi.CopyTo(Path.Combine(target.FullName, fi.Name), true);
        }

        // Copy each subdirectory using recursion.
        foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
        {
            DirectoryInfo nextTargetSubDir =
                target.CreateSubdirectory(diSourceSubDir.Name);
            CopyAll(diSourceSubDir, nextTargetSubDir);
        }
    }

    public static void Main()
    {
        string sourceDirectory = @"c:\sourceDirectory";
        string targetDirectory = @"c:\targetDirectory";

        Copy(sourceDirectory, targetDirectory);
    }

    // Output will vary based on the contents of the source directory.
}
123
ответ дан 22 November 2019 в 22:38
поделиться

Рекурсивно копировать папку без рекурсии, чтобы избежать переполнения стека.

public static void CopyDirectory(string source, string target)
{
    var stack = new Stack<Folders>();
    stack.Push(new Folders(source, target));

    while (stack.Count > 0)
    {
        var folders = stack.Pop();
        Directory.CreateDirectory(folders.Target);
        foreach (var file in Directory.GetFiles(folders.Source, "*.*"))
        {
            File.Copy(file, Path.Combine(folders.Target, Path.GetFileName(file)));
        }

        foreach (var folder in Directory.GetDirectories(folders.Source))
        {
            stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));
        }
    }
}

public class Folders
{
    public string Source { get; private set; }
    public string Target { get; private set; }

    public Folders(string source, string target)
    {
        Source = source;
        Target = target;
    }
}
14
ответ дан 22 November 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: