Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C#扫描具有向下钻取功能的驱动器?_C#_File_Comparison - Fatal编程技术网

使用C#扫描具有向下钻取功能的驱动器?

使用C#扫描具有向下钻取功能的驱动器?,c#,file,comparison,C#,File,Comparison,我正在尝试创建一个扫描驱动器的应用程序。不过,棘手的是,我的驱动器包含一组文件夹,这些文件夹中包含文件夹和文档。我正在尝试扫描驱动器,拍摄所有文档和文件夹的“快照”,并将其转储到.txt文件中。 第一次运行此应用程序时,输出将是一个包含所有文件夹和文件的文本文件。 第二次运行此应用程序时,它将获取2个文本文件(第二次运行应用程序时生成的文本文件和第一次运行应用程序时生成的.txt文件),并对它们进行比较…报告已移动/覆盖/删除的内容 有人有这方面的代码吗?我是这方面的新手,任何帮助都将不胜感激

我正在尝试创建一个扫描驱动器的应用程序。不过,棘手的是,我的驱动器包含一组文件夹,这些文件夹中包含文件夹和文档。我正在尝试扫描驱动器,拍摄所有文档和文件夹的“快照”,并将其转储到.txt文件中。
第一次运行此应用程序时,输出将是一个包含所有文件夹和文件的文本文件。
第二次运行此应用程序时,它将获取2个文本文件(第二次运行应用程序时生成的文本文件和第一次运行应用程序时生成的.txt文件),并对它们进行比较…报告已移动/覆盖/删除的内容

有人有这方面的代码吗?我是这方面的新手,任何帮助都将不胜感激


提前感谢。

您可以轻松地使用DirectoryInfo/FileInfo类来完成此操作

基本上实例化DirectoryInfo类的一个实例,指向c:\文件夹。然后使用它的对象遍历文件夹结构

有可以很容易翻译的代码

现在,你问题的另一部分是精神错乱。您可以相对容易地找到这两个文件之间的差异,但是将其转换为已移动/删除的文件/etc需要一些相当高级的逻辑结构。毕竟,如果我有两个文件,都名为myfile.dat,其中一个位于c:\foo,另一个位于c:\notfoo,那么如果我删除了c:\foo中的一个,会如何报告c:\notfoo中的一个?另一个例子是,如果我有一个文件myfile2.dat,并将其从c:\bar复制到c:\notbar,这是否被视为移动?如果我在星期二复制它,然后在星期四删除c:\bar\myfile2.dat--这是移动还是删除?如果我在每周一而不是每天运行这个程序,答案会改变吗

有一大堆的问题,以及它们相应的逻辑结构,你需要考虑amd代码来构建这些功能,即使这样,它也不是100%正确的,由于它不会在发生更改时对文件系统进行分页,因此始终存在这样一种可能性:由于时间、逻辑结构、处理时间、应用程序运行的时间,或者仅仅由于计算机的异常性,在您的逻辑中无法正确报告某个场景


此外,处理时间将随着驱动器的大小呈指数增长。毕竟,您需要对照每个其他文件检查每个文件,以确定它的状态,而不是以前的状态。我不想在家里用600 GB以上的硬盘运行这个,更不用说在工作的服务器上用40 TB的硬盘了。

比文本文件比较更好的方法是使用

侦听文件系统更改通知,并在目录或目录中的文件更改时引发事件


您可以记录更改,然后根据需要从该日志生成报告。

我们在80年代学到的一件事是,如果使用递归进行文件系统遍历很有诱惑力,但一旦您这样做,就会有人创建一个具有嵌套级别的文件系统,从而导致堆栈溢出。使用基于堆的文件系统遍历要好得多

这是一个我自己设计的课程。它不是超级漂亮,但它做得很好:

using System;
using System.IO;
using System.Collections.Generic;

namespace DirectoryWalker
{
    public class DirectoryWalker : IEnumerable<string>
    {
        private string _seedPath;
        Func<string, bool> _directoryFilter, _fileFilter;

        public DirectoryWalker(string seedPath) : this(seedPath, null, null)
        {
        }

        public DirectoryWalker(string seedPath, Func<string, bool> directoryFilter, Func<string, bool> fileFilter)
        {
            if (seedPath == null)
                throw new ArgumentNullException(seedPath);
            _seedPath = seedPath;
            _directoryFilter = directoryFilter;
            _fileFilter = fileFilter;
        }

        public IEnumerator<string> GetEnumerator()
        {
            Queue<string> directories = new Queue<string>();
            directories.Enqueue(_seedPath);
            Queue<string> files = new Queue<string>();
            while (files.Count > 0 || directories.Count > 0)
            {
                if (files.Count > 0)
                {
                    yield return files.Dequeue();
                }

                if (directories.Count > 0)
                {
                    string dir = directories.Dequeue();
                    string[] newDirectories = Directory.GetDirectories(dir);
                    string[] newFiles = Directory.GetFiles(dir);
                    foreach (string path in newDirectories)
                    {
                        if (_directoryFilter == null || _directoryFilter(path))
                            directories.Enqueue(path);
                    }
                    foreach (string path in newFiles)
                    {
                        if (_fileFilter == null || _fileFilter(path))
                            files.Enqueue(path);
                    }
                }
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

它递归地列出了以“.cs”结尾的所有文件。

我想说的是,文件比较将在文件夹之间进行。如中所示,上次运行应用程序时生成的.txt转储文件中的C:\foo将与上次运行应用程序时的C:\foo进行比较。如果我打算这样做,它仍然是疯狂的吗?这稍微有点不同,稍微不那么疯狂,因为你们所做的只是比较X文件仍然在Y目录中。也就是说,Dennis Palmer有一个更好的主意,在FileSystemWatcher类(我不知道)中,利用服务/任务托盘应用程序在Fly上记录文件更改确实要容易得多,但“更好”取决于几个因素,主要是两次扫描之间的时间跨度和所需的准确性。是的,FileSystemWatcher是可以的,除非您一次收到大量文件,然后您需要知道如何处理这些文件。发生这种情况时,我无法获取所有事件(数千个文件同时被转储到我的系统中)。我所做的是等待任何文件事件,关闭事件挂钩,处理文件,完成后进行几秒钟的轮询以查看是否有更多的文件出现,重新启用FileSystemWatcher。答案比我的好得多,所以我正在删除我的。这就是我来这里的原因;像这样的好答案。回答这个问题的人有一篇关于这个概念的精彩后续文章:好代码。然而,仍然有一个内存不足的问题潜伏着。在几乎所有现代文件系统中,在遍历时可能会有循环(由于符号链接)!是的,Windows也有这个。你需要对此进行检测,否则你也会因为这种方法而内存不足。更好地使用Directory.GetFiles(…,SearchOption.AllDirectories)@plinth我遇到了管理错误。您是否有捕获授权问题的解决方案?
DirectoryWalker walker = new DirectoryWalker(@"C:\pathToSource\src", null, (x => x.EndsWith(".cs")));
foreach (string s in walker)
{
    Console.WriteLine(s);
}