2012-01-30 91 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