C #에서 디렉토리의 전체 내용을 복사하십시오. 하여이 작업을 수행 할 수있는 방법이

C #에서 디렉토리의 전체 내용을 한 위치에서 다른 위치로 복사하고 싶습니다.

System.IO많은 재귀가없는 클래스를 사용 하여이 작업을 수행 할 수있는 방법이 없는 것 같습니다 .

VB에는 다음에 대한 참조를 추가 할 때 사용할 수있는 방법이 있습니다 Microsoft.VisualBasic.

new Microsoft.VisualBasic.Devices.Computer().
    FileSystem.CopyDirectory( sourceFolder, outputFolder );

이것은 다소 추악한 해킹처럼 보입니다. 더 좋은 방법이 있습니까?



답변

훨씬 쉽게

//Now Create all of the directories
foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", 
    SearchOption.AllDirectories))
    Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));

//Copy all the files & Replaces any files with the same name
foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", 
    SearchOption.AllDirectories))
    File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);

답변

흠, 나는 그 질문을 오해하고 있다고 생각하지만 나는 그것을 위험에 빠뜨릴 것이다. 다음과 같은 간단한 방법으로 무엇이 잘못 되었습니까?

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));
}

편집 이 게시물에 똑같이 간단한 질문에 대한 간단한 대답에 대한 인상적인 수의 다운 보트가 생겼으므로 설명을 추가하겠습니다. 제발 downvoting 전에 반드시 숙지 .

우선, 이 코드는 문제의 코드를 대체 하는 것으로 의도 된 것은 아닙니다 . 설명을 위해서만 사용하십시오.

Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory이 답변에서 누락 된 몇 가지 추가 정확성 테스트 (예 : 소스 및 대상이 유효한 디렉토리인지, 소스가 대상의 부모인지 등)를 수행합니다. 이 코드는 아마도 더 최적화되었을 것입니다.

즉, 코드 가 잘 작동합니다 . 그것은 (거의 동일) 년 동안 성숙한 소프트웨어에 사용되었습니다. 모든 IO 처리에 따른 고유 한 결함 (예를 들어 코드를 작성하는 동안 사용자가 USB 드라이브를 수동으로 분리하면 어떻게됩니까?) 외에 알려진 문제는 없습니다.

특히, 여기서 재귀를 사용하는 것이 문제가되지 않는다는 것을 지적하고 싶습니다. 이론적으로 (개념적으로 가장 우아한 솔루션 임) 또는 실제로 는 아닙니다 . 이 코드는 스택을 오버플로하지 않습니다 . 스택은 깊이 중첩 된 파일 계층 구조를 처리 할 수있을만큼 충분히 큽니다. 스택 공간이 문제가되기 훨씬 전에 폴더 경로 길이 제한이 시작됩니다.

• 그래도주의 악의적 인 사용자가 하나 개의 문자 각각의 깊게 중첩 된 디렉토리를 사용하여이 가정을 파괴 할 수 있습니다. 나는 이것을 시도하지 않았습니다. 그러나 요점을 설명하기 위해 :이 코드를 일반적인 컴퓨터에서 오버플로하려면 디렉토리를 수천 번 중첩해야합니다 . 이것은 단순히 현실적인 시나리오가 아닙니다.


답변

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.
}

답변

이 시도:

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 인수는 다를 수 있지만 아이디어를 얻습니다.


답변

또는 어려운 방향으로 가고 싶다면 Microsoft.VisualBasic 용 프로젝트에 대한 참조를 추가 한 후 다음을 사용하십시오.

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

그러나 재귀 함수 중 하나를 사용하는 것이 VB dll을로드 할 필요가 없으므로 더 좋은 방법입니다.


답변

이 사이트는 항상 많은 도움을 받았고 이제 다른 사람들을 내가 아는 것을 도울 차례입니다.

아래 코드가 누군가에게 유용하기를 바랍니다.

string source_dir = @"E:\";
string destination_dir = @"C:\";

// substring is to remove destination_dir absolute path (E:\).

// Create subdirectory structure in destination    
    foreach (string dir in System.IO.Directory.GetDirectories(source_dir, "*", System.IO.SearchOption.AllDirectories))
    {
        System.IO.Directory.CreateDirectory(System.IO.Path.Combine(destination_dir, dir.Substring(source_dir.Length + 1)));
        // Example:
        //     > C:\sources (and not C:\E:\sources)
    }

    foreach (string file_name in System.IO.Directory.GetFiles(source_dir, "*", System.IO.SearchOption.AllDirectories))
    {
        System.IO.File.Copy(file_name, System.IO.Path.Combine(destination_dir, file_name.Substring(source_dir.Length + 1)));
    }

답변

스택 오버플로를 피하기 위해 재귀없이 폴더를 재귀 적으로 복사하십시오.

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;
    }
}