簡體   English   中英

如何在C#中將一個文件集合與另一個文件集合進行比較?

[英]How do I compare one collection of files to another in c#?

我正在學習C#(已經花了大約2天的時間),並且我決定出於傾斜的目的,我將重建一個用VB6制作的舊應用程序,用於同步文件(通常跨網絡)。

當我用VB 6編寫代碼時,它的工作原理大致如下:

  1. 創建一個Scripting.FileSystemObject
  2. 創建源和目標的目錄對象
  3. 創建源和目標的文件列表對象
  4. 遍歷源對象,並檢查其是否存在於目標中
    • 如果沒有,創建它
    • 如果是這樣,請檢查源版本是否較新/更大,如果是,則覆蓋另一個

到目前為止,這就是我所擁有的:

private bool syncFiles(string sourcePath, string destPath) {
    DirectoryInfo source = new DirectoryInfo(sourcePath);
    DirectoryInfo dest = new DirectoryInfo(destPath);

    if (!source.Exists) {
        LogLine("Source Folder Not Found!");
        return false;
    }

    if (!dest.Exists) {
        LogLine("Destination Folder Not Found!");
        return false;
    }

    FileInfo[] sourceFiles = source.GetFiles();
    FileInfo[] destFiles = dest.GetFiles();

    foreach (FileInfo file in sourceFiles) {
        // check exists on file
    }

    if (optRecursive.Checked) {
        foreach (DirectoryInfo subDir in source.GetDirectories()) {
            // create-if-not-exists destination subdirectory
            syncFiles(sourcePath + subDir.Name, destPath + subDir.Name);
        }
    }
    return true;
}

我已經閱讀了一些示例,這些示例似乎主張使用FileInfo或DirectoryInfo對象對“ Exists”屬性進行檢查,但是我正在尋找一種方法來搜索現有的文件集合/列表,而不是對文件系統進行實時檢查。對於每個文件,由於我將通過網絡進行操作並不斷返回到數千個文件目錄,因此它很慢,很慢,很慢。

提前致謝。

GetFiles()方法只會獲取確實存在的文件。 它不會構成不存在的隨機文件。 因此,您要做的就是檢查它是否存在於其他列表中。

這樣的事情可能會起作用:

var sourceFiles = source.GetFiles();
var destFiles = dest.GetFiles();

foreach (var file in sourceFiles)
{
    if(!destFiles.Any(x => x.Name == file.Name))
    {
        // Do whatever
    }
}

注意: 當然,您無法保證在完成對GetFiles()的調用后某些內容沒有更改。 例如,如果您以后嘗試復制文件,則該文件可能已被刪除或重命名。


可以通過使用Except方法或類似方法更好地完成。 例如這樣的事情:

var sourceFiles = source.GetFiles();
var destFiles = dest.GetFiles();

var sourceFilesMissingInDestination = sourceFiles.Except(destFiles, new FileNameComparer());

foreach (var file in sourceFilesMissingInDestination)
{
    // Do whatever
}

FileNameComparer的實現方式如下:

public class FileNameComparer : IEqualityComparer<FileInfo>
{
    public bool Equals(FileInfo x, FileInfo y)
    {
        return Equals(x.Name, y.Name);
    }


    public int GetHashCode(FileInfo obj)
    {
        return obj.Name.GetHashCode();
    }
}     

未經測試:p

一個小細節,而不是

 sourcePath + subDir.Name

我會用

 System.IO.Path.Combine(sourcePath, subDir.Name)

Path對文件名和文件夾名執行可靠的,獨立於操作系統的操作。

我也注意到optRecursive.Checked突然出現。 為了達到良好的設計效果,請將該參數設為:

bool syncFiles(string sourcePath, string destPath, bool checkRecursive)

並且由於您提到它可能用於大量文件,因此請注意.NET 4,它具有IEnumerable替代GetFiles()的功能,可讓您以流式處理方式進行處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM