Итератор файловой системы Записывает результаты в CSV? - PullRequest
0 голосов
/ 30 января 2012

Я пытаюсь написать итератор файловой системы как простое приложение Windows.Я выложу что у меня так.Проблема в том, что когда я выбираю «C: \» для итерации, приложение блокируется.Если я выбираю каталог, скажем, Мои документы, он работает просто отлично.Что я делаю неправильно?Общая цель - записать результаты итерации в CSV-файл.Если бы вы могли помочь с этим, я был бы очень признателен.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;


namespace FileIterator
{
    class Iterator
    {

    public class MyItem
    {
        public static string it { get; set; }
    }

    public class Record
    {
        public long fileSize { get; set; }
        public string fileName { get; set; }

    }

    static List<Record> fileList = new List<Record>();

    public static void Iterate(string dir_tree)
    {
        Stack<string> dirs = new Stack<string>(20);

        if (!Directory.Exists(dir_tree))
        {
            MessageBox.Show("The directory you selected does not exist.", "Directory Selection Error",
            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
        dirs.Push(dir_tree);

        while (dirs.Count > 0)
        {
            string currentDir = dirs.Pop();
            string[] subDirs;
            try
            {
                subDirs = Directory.GetDirectories(currentDir);
            }

            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("You do not have permission to access this folder", "Directory Permission Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                continue;
            }

            catch (DirectoryNotFoundException)
            {
                MessageBox.Show("The current directory does not exist", "Directory Not Found",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                continue;
            }

            string[] files = null;

            try
            {
                files = System.IO.Directory.GetFiles(currentDir);
            }

            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("You do not have permission to access this folder", "Directory Permission Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                continue;
            }

            catch (DirectoryNotFoundException)
            {
                MessageBox.Show("The current directory does not exist", "Directory Not Found",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                continue;
            }



            foreach (string file in files)
            {
                try
                {
                    FileInfo fi = new FileInfo(file);
                    fileList.Add( new Record {
                        fileName = fi.Name,
                        fileSize = fi.Length
                    });
                }

                catch (FileNotFoundException)
                {
                    MessageBox.Show("The current file does not exist" + file, "File Not Found",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    continue;
                }
            }

            foreach (string str in subDirs)
                dirs.Push(str);
        }




    }

Form.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace FileIterator
{
    public partial class Form1 : Form
    {
        public Form1()
    {
        InitializeComponent();
    }

    private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
    {

    }
    string directory = " ";

    private void button1_Click(object sender, EventArgs e)
    {
        folderBrowserDialog1.ShowDialog();
        directory = folderBrowserDialog1.SelectedPath;
        DirectoryName.Text = folderBrowserDialog1.SelectedPath;
        Iterator.Iterate(directory);

    }



}

}

Ответы [ 3 ]

2 голосов
/ 30 января 2012

вы помещаете dir_tree в свой стек даже после того, как определите, что он не существует.Я думаю, что это ваша главная проблема здесь:

    if (!Directory.Exists(dir_tree))
            {
                MessageBox.Show("The directory you selected does not exist.", "Directory Selection Error",
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
// maybe you should return or something here....
            }
            dirs.Push(dir_tree);
1 голос
/ 30 января 2012

Попытка этого на C: \ займет ДЛИННОЕ время, файлов много, и обработка может занять несколько минут, все время пользовательский интерфейс будет заморожен.Как упоминалось выше, фоновый работник - лучший план, если вы действительно хотите это сделать.

Другие комментарии

Расположение стеков здесь громоздкое, вам это нужно?(Это домашнее задание / учебное упражнение?) Более простая идея - просто пройтись вниз по дереву, повторно вызывая Итерацию на каждом уровне

например

private class FileIterator {

    public IEnumerable<Record> Iterate(string path) {

        var currentFiles = new List<Record>(
            Directory.GetFiles(path).Select(file => {
                var fi = new FileInfo(file);
                return new Record{FileName = fi.Name, FileSize = fi.Length};
            }
        ));

        var childFiles = Directory.GetDirectories(path).SelectMany(dir => Iterate(dir));
        return currentFiles.Union(childFiles);

    }
}

Заметки:

Я опустил проверки безопасности только для того, чтобы ускорить кодирование с моей стороны, вы все равно можете их проверять.В каталоге не найдены чеки, хотя я сомневаюсь?Может ли содержимое файловой системы измениться во время выполнения вашей программы?Ожидается ли это регулярным явлением?

Кроме того, вызовы Messagebox здесь не очень хороши.Они путают любые попытки автоматизированного юнит-тестирования.

hth,Алан.

1 голос
/ 30 января 2012

Я думаю, что главная проблема здесь в том, что вы пытаетесь загрузить все в стек для начала.Ваша программа, вероятно, не зависает, она просто отрабатывает попытки рекурсивно перебирать тысячи файлов и папок на вашем компьютере.Это займет длинное время.

Почему бы не записать в CSV-файл по ходу дела, чтобы хотя бы увидеть прогресс?Вы также можете захотеть использовать BackgroundWorker , чтобы вы могли поддерживать адаптивный интерфейс и, возможно, продемонстрировать некоторый прогресс по мере того, как алгоритм работает в файловой системе.

...