2013-07-25 2 views
0

자신에 폴더를 복사 할 때 무한 루프에 가서 사용자 정의 디렉토리에 복사 기능을 방지하는 다른 위치에 복사 파일과 모든 폴더에서 파일 및 관련 하위 폴더 :나는이 기능을 시도하고있다

using System.IO; 

private static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting) 
     { 
      bool ret = true; 
      try 
      { 
       SourcePath = SourcePath.EndsWith(@"\") ? SourcePath : SourcePath + @"\"; 
       DestinationPath = DestinationPath.EndsWith(@"\") ? DestinationPath : DestinationPath + @"\"; 

       if (Directory.Exists(SourcePath)) 
       { 
        if (Directory.Exists(DestinationPath) == false) 
         Directory.CreateDirectory(DestinationPath); 

        foreach (string fls in Directory.GetFiles(SourcePath)) 
        { 
         FileInfo flinfo = new FileInfo(fls); 
         flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting); 
        } 

        foreach (string drs in Directory.GetDirectories(SourcePath)) 
        { 
         DirectoryInfo drinfo = new DirectoryInfo(drs); 
         if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false || drs.Substring(drs.Length-8) == "archive") 
          ret = false; 
        } 
       } 
       else 
       { 
        ret = false; 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("{0} {1} {2}", e.Message, Environment.NewLine + Environment.NewLine, e.StackTrace); 
       ret = false; 
      } 
      return ret; 
     } 

그것은 다른 위치로 폴더를 복사해야 할 때까지 작동하지만, 그 자체로 폴더를 만들어야 할 때 (필자는 "archive"라는 하위 폴더를 사용하여 마지막 폴더 파일 변경 사항을 추적합니다) 무한 루프에서는 Directory.GetDirectory foreach 루프에서 자체적으로 재검색을 계속하기 때문에 새로 만든 하위 폴더를 찾아 "Path name too long max 260 charachters limit"에 도달 할 때까지 동일한 하위 폴더를 반복해서 중첩합니다 예외".

나는 조건

를 사용하여 그것을 피하기 위해 노력 || drs.Substring (drs.Length-8) == "archive")

디렉토리 이름을 확인해야하지만 작동하지 않는 것 같습니다.

나는 중첩 된 폴더를 모두 재검색하지 않도록 최대 하위 폴더 깊이 검사 (I.E 최대 2 개의 하위 폴더)를 넣는 것과 같은 다른 솔루션을 생각했지만 Directory 개체에서 이러한 속성을 찾을 수 없습니다.

다음 번에 스캔 할 때 전체 폴더를 임시 폴더와 실제 폴더로 복사 할 수 없으므로 폴더를 다시 스캔합니다.

Directory 개체의 ArrayList에 모든 디렉터리 목록을 넣으려고하면 어쩔 수 없지만 DirName과 같은 것을 확인할 수는 있지만 그런 속성이 있는지는 알 수 없습니다.

모든 솔루션?

+0

이미 문자열 전에 운을 시도하지 않습니다. 심지어 디버거에서 가져온 정확한 문자열 값을 비교해도 결과가 없습니다. –

답변

0

복사 할 때 디렉터리 및 파일 목록이 항상 변경되므로 재귀가 실제로 작동하지 않는 경우입니다. 더 나은 해결책은 미리 모든 파일과 폴더의 목록을 가져 오는 것입니다.

SearchOption이 SearchOption.AllDirectories으로 설정된 Directory.GetFiles(String,String,SearchOption)Directory.GetDirectories(String,String,SearchOption)을 사용하여 트리의 모든 파일과 디렉토리를 가져올 수 있습니다. 그러면 모든 파일과 모든 디렉토리가 각각 반환됩니다.

당신은 파일을 복사하려면 다음이 단계를 수행 할 수 있습니다

  1. 모든 소스 디렉토리의 목록을 얻고 오름차순으로 정렬. 이렇게하면 상위 디렉토리가 하위 디렉토리 앞에 표시됩니다.
  2. 하위 디렉터리를 정렬 된 순서로 만들어 대상 디렉터리 구조를 만듭니다. 정렬 순서에 따라 하위 폴더 이전에 항상 상위 폴더를 만들 수 있으므로 경로 충돌이 발생하지 않습니다.
  3. 이전과 마찬가지로 모든 소스 파일을 대상 디렉토리에 복사하십시오. 목표 디렉토리 구조가 이미 존재하므로이 시점에서는 순서가 중요하지 않습니다.

빠른 예 :

static void Main(string[] args) 
    { 
     var sourcePath = @"c:\MyRoot\TestFolder\"; 

     var targetPath = @"c:\MyRoot\TestFolder\Archive\"; 

     var directories=Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories); 
     var files = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories); 

     if(!Directory.Exists(targetPath)) 
      Directory.CreateDirectory(targetPath); 

     foreach (var directory in directories) 
     { 
      var relativePath = GetRelativePath(sourcePath, directory); 
      var toPath = Path.Combine(targetPath, relativePath); 
      if (!Directory.Exists(toPath)) 
      { 
       Directory.CreateDirectory(toPath); 
      } 
     } 

     foreach (var file in files) 
     { 
      var relativePath = GetRelativePath(sourcePath, file); 
      var toPath = Path.Combine(targetPath, relativePath); 
      if (!File.Exists(toPath)) 
       File.Copy(file,toPath); 
     } 
    } 

    //This is a very quick and dirty way to get the relative path, only for demo purposes etc 
    private static string GetRelativePath(string rootPath, string fullPath) 
    { 
     return Path.GetFullPath(fullPath).Substring(rootPath.Length); 
    }