0

私はC#で書かれた「復元」プログラムを持っています。これは、ある時点で4つの特定のタイプのファイルを探し、それらのタイプのファイルのいずれかをディレクトリに移動し(存在しない場合は最初にそのディレクトリを作成します)、次にバックアップからファイルを書き込む前に、これらのタイプのファイルのすべてのインスタンスをディレクトリに移動します。これが私のコードのセクションです:

private void restoreFromBackup(string chosenFile)
{
    this
    .Cursor = Cursors.WaitCursor;

    // Create new directory in which to move existing .bin and .hid files on the PC

    if (!Directory.Exists("C:\\Phoenix\\OldBinHid"))
    {
        Directory.CreateDirectory("C:\\Phoenix\\OldBinHid");
    }
    else
    {
        Array.ForEach(Directory.GetFiles(@"C:\\Phoenix\\OldBinHid"), File.Delete);
    }

    // Move existing .bin and .hid files to the new directory

    string pattern = @"(\.bin|\.hid|\.BIN|.HID)$";
    var files = Directory.GetFiles(@"C:\Phoenix")
        .Where(x => Regex.IsMatch(x, pattern))
        .Select(x => x).ToList();

    foreach (var item in files)
    {
        Console.WriteLine(item);
        string name = item.Substring(item.LastIndexOf("\\") + 1);
        File.Move(item, Path.Combine(@"C:\Phoenix\OldBinHid", name));
    }

ディレクトリの作成は問題なく機能しますが、各タイプのファイル (Test.bin、Test.BIN、Test.hid、および Test.HID) の例を 1 つ C:\Phoenix ディレクトリに配置しましたが、どれもうまくいきませんでした。 C:\Phoenix\OldBinHid ディレクトリに移動しました。次に、同様のテスト ファイルのコピーを C:\Phoenix\OldBinHid ディレクトリに置き、2 回目の復元を実行しましたが、そのディレクトリ内のファイルも削除されませんでした。

ここで何が間違っていますか?

どんな助けでも大歓迎です。

ありがとうございました


うーん、まだやりたいことができていません。復元は、オフサイトの場所の 1 つが新しい PC を受け取り、デフォルトの .bin および .hid ファイルが自動的にロードされたときに行います。しかし、オフサイトの場所では、以前の PC に多数の異なる .bin および .hid ファイルが構築されている可能性が高く、前の晩に特定のファイルを圧縮して別の PC にバックアップする必要がありました。 .bin および .hid ファイル。私がする必要があるのは、復元プログラムに C:\Phoenix\OldBinHid ディレクトリが既に存在するかどうかを確認させることです (技術的にはそうすべきではありませんが、他の問題がある場合は古い PC を元の場所に戻す必要がある場合があります)。新しい PC) が存在する場合は、そこにあるすべてのファイルを削除します。存在しない場合は、C:\Phoenix\OldBinHid ディレクトリを作成する必要があります。

昨夜、いくつかのテスト ファイル (TestA.bin、TestB.BIN、TestC.hid、TestD.HID) を \Phoenix ディレクトリに置いたので、それらはバックアップされます。また、OldBinHid ディレクトリにはいくつかのテスト ファイルがありました。それから、最初に復元プログラムで行った修正をいくつか試してみました、サイモン。動作しませんでした - プログラムは実行されましたが、\OldBinHid ディレクトリから何も削除されず、テスト ファイルもそこに移動されませんでした。次に、さらにいくつかのテスト ファイルを追加したので、\Phoenix ディレクトリに余分なテスト ファイルが存在することはわかっていたので、Restore を再度実行しました。まだディレクトリには何も移動されておらず、元のテスト ファイルは \OldBinHid ディレクトリに残っています。だから私はあなたのよりきれいなバージョンに行きました-これが私が持っているものです:

        // Create new directory in which to move existing .bin and .hid files on the PC

        string sourceDirectory = @"C:\Phoenix";
        string destinationDirectory = @"C:\Phoenix\OldBinHid";
        string pattern = @"(\.bin|\.hid)$";

        Directory.CreateDirectory(destinationDirectory);
        Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);

        // Move existing .bin and .hid files to the new directory

        var files = Directory.GetFiles(sourceDirectory)
            .Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase))
            .Select(x => x)
            .ToArray();

        Array.ForEach(files, file =>
        {
            Console.WriteLine(file);
            File.Move(file, Path.Combine(destinationDirectory, Path.GetFileName(file)));
        });

それでもエラーなしで実行されましたが、何も削除または移動されませんでした。ここでまだ何かが足りないのですか?

4

1 に答える 1

2

コンソールアプリをノックアップしてコードをコピーしました。@Zong Zheng が言うように、文字列リテラルを使用している場合は、二重のバックスラッシュを削除する必要があります。そう

@"C:\Phoenix\.."

それ以外の

@"C:\\Phoenix\\.."

それは私のために働いた。これが私のコードです(あなたのコードに基づいています):

class Program
{
    static void Main(string[] args)
    {
        restoreFromBackup("");
    }

    private static void restoreFromBackup(string chosenFile)
    {
        // Create new directory in which to move existing .bin and .hid files on the PC

        if (!Directory.Exists(@"G:\temp\test2\test3"))
        {
            Directory.CreateDirectory(@"G:\temp\test2\test3");
        }
        else
        {
            Array.ForEach(Directory.GetFiles(@"G:\temp\test2\test3"), File.Delete);
        }

        // Move existing .bin and .hid files to the new directory

        string pattern = @"(\.bin|\.hid|\.BIN|.HID)$";
        var files = Directory.GetFiles(@"G:\temp\test2")
            .Where(x => Regex.IsMatch(x, pattern))
            .Select(x => x).ToList();

        foreach (var item in files)
        {
            Console.WriteLine(item);
            string name = item.Substring(item.LastIndexOf("\\") + 1);
            File.Move(item, Path.Combine(@"G:\temp\test2\test3", name));
        }
    }
}

両方の動作を示します。ディレクトリが存在する場合、そこにあるものはすべて削除されます。存在しない場合は作成します。

次に、すべてのファイルをベース ディレクトリからサブディレクトリにコピーします。

ただし、二重バックスラッシュと文字列リテラル文字 @ を混在させると、機能しなくなります。

また、私は間違いなくこの行を変更します:

string name = item.Substring(item.LastIndexOf("\\") + 1);

string name = Path.GetFilename(item);

組み込みであるため、よりクリーンで読みやすく、無料です。

さらなる改善として、Regex.IsMatch メソッドのこのオーバーロードを使用し、RegexOptions パラメータで「IgnoreCase」を指定することを検討します。次に、.BIN/.bin の組み合わせを取り除くことができます。これが問題の原因である可能性があります (確認していませんが) - フォルダー内のファイルが Something.bin や Something.BIN ではなく、Something.Bin である場合はどうなりますか? 大文字と小文字を区別しないと、その問題が解消されます。

以下は、同じコードの少しきれいなバージョンです。

    private static void restoreFromBackup(string chosenFile)
    {
        string sourceDirectory = @"G:\temp\test2";
        string destinationDirectory = @"G:\temp\test2\test3";
        string pattern = @"(\.bin|\.hid)$";

        // Create new directory in which to move existing .bin and .hid files on the PC
        Directory.CreateDirectory(destinationDirectory);
        Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);

        var files = Directory.GetFiles(sourceDirectory)
            .Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase))
            .Select(x => x)
            .ToArray();

        Array.ForEach(files, file => 
        {
            Console.WriteLine(file);
            File.Move(file, Path.Combine(destinationDirectory, Path.GetFileName(file))); 
        });
    }

これがお役に立てば幸いです。

編集

あなたのフィードバック (まだ動作していません) を考慮して、詳細なデバッグを行うために、プログラムにいくつかの変更を加える必要があります。

1.まず、この行を分割します

Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);

2行に:

var filesToDelete = Directory.GetFiles(destinationDirectory);
Array.ForEach(filesToDelete, File.Delete);

var filesToDelete...行の後にブレークポイントを置き、 filesToDeleteに監視を追加します。何が見えますか?filesToDelete 変数にファイル名はありますか?

2. foreach にブレークポイントを設定します (ファイル内の var 項目)。

そして、ファイル変数にウォッチを追加します。繰り返しますが、何が見えますか?

どこで失敗したかを確認するには、分解を開始する必要があります。

この段階で、私のお金は (不足している) アクセス許可か、間違ったパス/ドライブ文字/ワイルドカードのいずれかにあります。正しいフォルダを見ていますか? ドライブレター?

何もしない傾向はありません。それらは機能するか、例外を生成します。「何も起こらない」ことはよくありません。ループが実際にループしないようにフィルタリングしていない限り。

C# のデバッグ スキルを磨いて、レポートを返してください...

また、実行している環境についても説明してください。ファイルはローカルの物理ドライブ上にありますか?それともネットワーク上にありますか? Windows のバージョンは? .NET Windows ですか、それとも MONO ですか? どのマシンで実行していますか? ファイルのサイズ?ディスクスペース?等

于 2013-10-22T21:12:40.230 に答える