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

代わりに1つの小さな詳細

 sourcePath + subDir.Name

私は使うだろう

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

Pathは、ファイル名とフォルダー名に対して、OSに依存しない信頼性の高い操作を実行します。

optRecursive.Checkedまた、どこからともなく飛び出しているのに気づきました。優れた設計の問題として、それをパラメータにします。

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

また、多数のファイルに使用される可能性があるとおっしゃっていますので、.NET 4に注意してください。これは、GetFiles()のIEnumerable置換であり、ストリーミング方式で処理できます。

于 2009-12-06T11:14:06.743 に答える