2012-01-30 90 views
0

我想写一个文件系统迭代器作为一个简单的Windows应用程序。我会发布我拥有的。问题是,当我选择“C:\”进行迭代时,应用程序锁定。如果我从“我的文档”中选择一个目录,它就可以正常工作。我究竟做错了什么?总体目标是将迭代的结果写入csv文件。如果你能提供帮助,我也会非常感激。文件系统迭代器将结果写入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); 

    } 



} 

}

+2

尝试单步执行调试程序中的代码... – 2012-01-30 16:52:34

+0

[迭代文件系统并将结果写入CSV文件](http://stackoverflow.com/questions/9068408/iterate-a-file-system -and-write-results-to-csv-file) – 2012-01-30 19:05:41

回答

2

你推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

我认为这里的主要问题是,你正试图加载一切到堆栈开始。你的程序可能不会被冻结,它只是试图递归迭代你机器上的数千个文件和文件夹。这是要采取时间。

为什么不写CSV文件,当您去,这样你至少可以看到进展?您可能还需要使用BackgroundWorker,这样就可以保持UI响应,并可能表现出一定的进步为算法的工作原理是通过文件系统的方式。

+0

我非常喜欢在程序运行时编写CSV的想法。我该怎么做? – broguyman 2012-01-30 17:32:49

+1

真的很简单。不要创建Record实例,只需将所需数据写入文件。您可能希望创建一个'FileStream'并将其包装在Iterate函数开头的'StreamWriter'中,然后在整个函数中使用它。看看StreamWriter.WriteLine:http://msdn.microsoft.com/en-us/library/system.io.streamwriter.writeline.aspx。最后,确保你在最后冲洗()你的流。 – 2012-01-30 18:30:40

1

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

    } 
} 

注:

我省略了安全检查只是为了加快我的一部分编码,你还可以进行检查。目录未找到,但我可疑吗?文件系统内容在您的程序执行时可能会发生变化吗?预计这是一个经常发生?

此外,消息框调用是不好在这里。他们搞砸了自动化单元测试的任何尝试。

心连心,
艾伦。

+0

这只是训练练习。目前我是UNIX中的C程序员,我正在尝试获得新工作,并且我几乎是C#的一个小菜鸟,我只是想用这个项目来感受一下C#和.NET编程。 – broguyman 2012-01-30 17:34:15