0

我刚刚学习 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”属性进行检查的示例,但我专门寻找一种方法来搜索现有的文件集合/列表,而不是对文件系统进行实时检查对于每个文件,因为我将通过网络这样做并且不断地回到一个多文件目录是慢慢慢。

提前致谢。

4

2 回答 2

5

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

于 2009-12-06T11:09:03.713 回答
4

一个小细节,而不是

 sourcePath + subDir.Name

我会用

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

Path 对文件名和文件夹名执行可靠的、独立于操作系统的操作。

我还注意到optRecursive.Checked突然冒出来。作为一个好的设计,把它作为一个参数:

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

而且由于您提到它可能用于大量文件,因此请留意 .NET 4,它有一个 GetFiles() 的 IEnumerable 替代品,可以让您以流式方式处理它。

于 2009-12-06T11:14:06.743 回答