0

我有一个用 C# 编写的“恢复”程序,它有时需要查找四种特定类型的文件,将这些类型的文件中的任何一种移动到一个目录(如果该目录不存在,则首先创建该目录),然后在从备份写入文件之前,将这些类型文件的所有实例移动到目录中。这是我的代码部分:

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));
    }

创建目录工作得很好,但即使我在 C:\Phoenix 目录中放置了每种类型的文件(Test.bin、Test.BIN、Test.hid 和 Test.HID)的一个示例,但它们都不是移动到 C:\Phoenix\OldBinHid 目录。然后,我还将类似测试文件的副本放在 C:\Phoenix\OldBinHid 目录中,并第二次运行了我的恢复 - 它也没有删除该目录中的任何文件。

我在这里有什么问题?

任何帮助将不胜感激。

谢谢


嗯 - 它仍然没有做我想要它做的事情。当我们的一个异地位置收到一台新 PC 时,将进行恢复,该 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 目录中会有额外的测试文件并再次运行我的还原。仍然没有任何东西移动到目录中,原始测试文件仍然在 \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);

分为两行:

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

在var filesToDelete...行之后放置一个断点并在 filesToDelete 上添加一个监视。你看到了什么?filesToDelete 变量中是否有任何文件名?

2.在foreach上下断点(var item in files)

并在 files 变量上添加一个监视。再说一遍,你看到了什么?

您需要开始分解它以查看它失败的地方。

在这个阶段,我的钱现在要么(缺乏)权限要么不正确的路径/驱动器号/通配符。您确定您正在查看正确的文件夹吗?驱动器号?

事情往往不会做任何事情。它们要么工作,要么产生异常。“什么都没有发生”的情况并不常见。除非您将内容过滤掉以使循环实际上不会循环。

放下你的 C# 调试技能并报告回来......

另外,请描述您正在运行的环境。文件是在本地物理驱动器上还是在网络上?什么版本的 Windows?它是 .NET Windows 还是 MONO?你在什么机器上运行?文件大小?磁盘空间?ETC

于 2013-10-22T21:12:40.230 回答