Сканирование диска с развертками с использованием C #? - PullRequest
2 голосов
/ 01 июня 2009

Я пытаюсь создать приложение, которое сканирует диск. Сложность состоит в том, что мой диск содержит набор папок, в которых есть папки внутри папок и которые содержат документы. Я пытаюсь отсканировать диск, сделать «снимок» всех документов и папок и создать дамп в файл .txt.
При первом запуске этого приложения выводится текстовый файл со всеми папками и файлами.
Во второй раз, когда я запускаю это приложение, он возьмет 2 текстовых файла (тот, который был получен во второй раз, когда я запускаю приложение, и файл .txt с первого раза, когда я запустил приложение) и сравню их ... сообщая был перемещен / переопределен / удален.

У кого-нибудь есть код для этого? Я новичок в этом C # материал, и любая помощь будет принята с благодарностью.

Заранее спасибо.

Ответы [ 3 ]

9 голосов
/ 01 июня 2009

Одна вещь, которую мы узнали в 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();
        }
    }
}

Типичное использование это:

DirectoryWalker walker = new DirectoryWalker(@"C:\pathToSource\src", null, (x => x.EndsWith(".cs")));
foreach (string s in walker)
{
    Console.WriteLine(s);
}

, который рекурсивно перечисляет все файлы, заканчивающиеся на ".cs"

1 голос
/ 01 июня 2009

Лучшим подходом, чем сравнение текстовых файлов, было бы использование FileSystemWatcher Class .

Прослушивает уведомления об изменении файловой системы и вызывает события при изменении каталога или файла в каталоге.

Вы можете зарегистрировать изменения и затем сгенерировать отчеты по необходимости из этого журнала.

0 голосов
/ 01 июня 2009

Вы можете легко использовать для этого классы DirectoryInfo / FileInfo.

По существу, экземпляр экземпляра класса DirectoryInfo указывает на папку c: \. Затем с помощью его объектов пройдитесь по структуре папок.

http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx имеет код, который можно легко перевести.

Теперь другая часть вашего вопроса - безумие. Вы можете найти различия между этими двумя файлами относительно легко, но преобразование этого в то, что было перемещено / удалено / и т. Д., Потребует некоторых довольно продвинутых логических структур. В конце концов, если у меня есть два файла, оба с именем myfile.dat, и один из них находится в c: \ foo, а другой - в c: \ notfoo, как будет поступать сообщение о том, что один в c: \ notfoo, если я удалил один в C: \ Foo? Другой пример, если у меня есть файл myfile2.dat и я скопирую его из c: \ bar в c: \ notbar, это считается ходом? Что произойдет, если я скопирую его во вторник, а затем в четверг удаляю c: \ bar \ myfile2.dat - это перемещение или удаление? И изменится ли ответ, если я запускаю программу каждый понедельник, а не ежедневно?

Существует целый ряд вопросов и соответствующих им логических структур, для которых вам нужно подумать о коде amd для создания этой функциональности, и даже в этом случае он не будет на 100% правильным, поскольку он не разбивает на страницы. Файловая система по мере изменений - всегда будет существовать вероятность того, что сценарий не будет правильно представлен в вашей логике из-за синхронизации, логической структуры, времени процесса, когда приложение запускается или просто из-за извращенности компьютеров.

Кроме того, время обработки будет расти в геометрической прогрессии в зависимости от размера вашего диска. В конце концов, вам нужно сравнить каждый файл с каждым другим файлом, чтобы определить его состояние, а не предыдущее. Я бы не хотел запускать это в домашних условиях на моем накопителе объемом 600 ГБ, не говоря уже о накопителях емкостью 40 ТБ, которые установлены на серверах в работе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...