我正在尝试将文件系统迭代器编写为一个简单的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);
}
}
}
答案 0 :(得分: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 :(得分:1)
我认为这里的主要问题是你试图将所有内容加载到堆栈中。你的程序可能并没有冻结,它只是试图递归迭代你机器上的数千个文件和文件夹。这将花费 长 时间。
为什么不随时写入CSV文件,以便至少可以看到进度?您还可能希望使用BackgroundWorker,以便您可以保持UI响应,并且可以显示一些进度,因为算法可以在文件系统中运行。
答案 2 :(得分:1)
在C:\上尝试这个将花费很长时间,有很多文件,可能需要几分钟才能处理,因为UI将被冻结。如上所述,如果你想这样做,背景工作者是最好的计划。
其他评论
这里的堆栈布置很麻烦你需要它吗? (这是一个家庭作业/训练练习吗?)一个更简单的想法就是通过在每个级别重新调用Iterate来递减树木
e.g。
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,
艾伦。