2017-12-18 25 views
3

파일 이름을 기준으로 서로 다른 두 개의 디렉터리에서 파일 목록을 비교할 수있는 방법을 쓰고 있습니다. 두 번째 디렉토리에 나중에 사용할 목록에 존재하지 않아야합니다 (대부분이 파일을 복사/이동할 다른 방법을 생성 할 가능성이 높습니다).C# 전체 경로를 반환하지 않는 이름을 기반으로하는 파일 목록을 비교하십시오.

파일 목록 (FilesRemaiing 목록)을보고 파일의 전체 경로를 가져 오기 전까지는 모든 것이 제대로 작동하는 것 같습니다. 그것은 내 빈/디버그 경로를 가리키는 끝납니다.

내 쿼리에서 파일을 쿼리하는 것이기 때문에 믿습니다. 파일이 아닌 비교할 파일 이름입니다. 전체 이름. 그 이유는 FullName이 경로와 파일 이름을 반환하기 때문입니다. 비교 문 (var FilesRemaining = FileList1.Except (FileList2) .ToList();)에 사용할 수 없습니다.

내 질문에 어떻게 이름을 기반으로 2 세트의 파일을 비교합니까? 그렇다면 나중에 복사/이동을 위해 사용할 수있는 제 3 목록에 예외 목록의 전체 경로를 저장 하시겠습니까?

여기 내 방법입니다 :

public static List<string> CompareFiles(string ComparePath1, string ComparePath2) 
    { 
     List<string> FileList1 = new List<string>(); 
     List<string> FileList2 = new List<string>(); 
     List<string> CompareFileList = new List<string>(); 
     DirectoryInfo directory1 = new DirectoryInfo(ComparePath1); 
     FileInfo[] files1 = directory1.GetFiles("*.*", SearchOption.TopDirectoryOnly); 
     DirectoryInfo directory2 = new DirectoryInfo(ComparePath2); 
     FileInfo[] files2 = directory2.GetFiles("*.*", SearchOption.TopDirectoryOnly); 

     //Queries the given directory for filenames 
     var query1 = from file in files1 
       where (!file.Attributes.HasFlag(FileAttributes.Hidden)) 
        select (file.Name); 
     foreach (var file in query1) 
     { 
      FileList1.Add(file); 
     } 

     var query2 = from file in files2 
        where (!file.Attributes.HasFlag(FileAttributes.Hidden)) 
        select (file.Name); 
     foreach (var file in query2) 
     { 
      FileList2.Add(file); 
     } 

     var FilesRemaining = FileList1.Except(FileList2).ToList(); 

     foreach (var file in FilesRemaining) 
     { 
      string fullFile = Path.GetFullPath(file); 
      CompareFileList.Add(fullFile); 
      Console.WriteLine(fullFile); 
     } 

     return CompareFileList; 

    } 
+0

는 filelist1의 & 2 '목록 을'다음'Except' 호출에 대해 로컬 평등 연산자를 사용하여 더 나을 것 같아 : https://msdn.microsoft.com/en-us /library/bb300779(v=vs.110).aspx 그런 다음 끝에 루프를 약간 조정하십시오. – zzxyz

+0

사실, 예외 대신 Where 호출 만 할 수 있습니다 ... – zzxyz

답변

3

이를 사용하여 객체에서는 FileInfo을 유지하고, 여전히 자신의 이름을 사용하여 목록을 제외하고를 계산할 수 있습니다.

//More efficient way to get your files. 
IEnumerable<FileInfo> files1 = directory1 
    .GetFiles("*.*", SearchOption.TopDirectoryOnly) 
    .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden)); 
IEnumerable<FileInfo> files2 = directory2 
    .GetFiles("*.*", SearchOption.TopDirectoryOnly) 
    .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden)); 

//It uses the FileNameComparer class to compare to values. 
IEnumerable<FileInfo> filesRemaining = files1.Except(files2, new FileNameComparer()); 

이며 여기에 FileNameComparer 클래스가 있습니다.

public class FileNameComparer : IEqualityComparer<FileInfo> 
{ 
    public bool Equals(FileInfo x, FileInfo y) 
    { 
     //Here is where the magic is happening. 
     return x.Name == y.Name; 
    } 

    //You need this too, altougt, I am not quite sure when it gets used. 
    public int GetHashCode(FileInfo obj) 
    { 

     return obj.Name.GetHashCode(); 
    } 
} 
+0

@Steve 무슨 말씀 이세요? 이것은 잘 컴파일됩니다. LINQ 구문을 사용하면 알 필요가 있지만, 알 수없는 것처럼 – rokkerboci

+0

오른쪽으로 이동 시간은 – Steve

+0

입니다. @Steve 나는 친구도 거기에 왔습니다. : D – rokkerboci

-1
class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (var f in CompareFiles(@"x:\tmp\dir_1", @"x:\tmp\dir_2")) 
     { 
      Console.WriteLine(f); 
     } 

     Console.ReadKey(); 
    } 

    public static List<string> CompareFiles(string comparePath1, string comparePath2) 
    { 
     //Queries the given directory for filenames 
     var fileList1 = (from file in new DirectoryInfo(comparePath1).GetFiles("*.*", SearchOption.TopDirectoryOnly) 
         where !file.Attributes.HasFlag(FileAttributes.Hidden) 
         select file.Name).ToList(); 

     var fileList2 = (from file in new DirectoryInfo(comparePath2).GetFiles("*.*", SearchOption.TopDirectoryOnly) 
         where !file.Attributes.HasFlag(FileAttributes.Hidden) 
         select file.Name).ToList(); 
     return fileList1.Except(fileList2) 
         .Select(file => Path.Combine(comparePath1, file)) 
         .ToList(); 
    } 
} 
+0

누군가가 왜 이것을 떨어 뜨린 지 궁금한가요? 그것은 합리적인 대답처럼 보입니다. – zzxyz

+0

확실하지 않지만이 솔루션을 사용해 보지 않았지만 다른 솔루션이 나에게 도움이되었습니다. –