编辑8/8/2012: 我对我正在使用的代码做了一些重大更改,并希望在最后一个代码上获得一些新的帮助我遇到的问题。我将重写这个问题的大部分内容。
我有一个小程序,它递归遍历目标目录下的每个文件和文件夹,检查特定字符的名称。它工作正常,但我正在寻求有关如何使特定方法更快地工作的帮助。
这是我目前正在使用的代码。这只是解决所有问题的方法中的几行:
if(getFullList(initialPathTB.Text))
SearchFolder();
这些是你需要看到的两种方法:
private void SearchFolder()
{
int newRow;
int numItems = 0;
numItems = itemsMaster.Length;
for (int x = 0; x < numItems; x++)
{
if (hasIllegalChars(itemsMaster[x]) == true)
{
newRow = dataGridView1.Rows.Add();
dataGridView1.Rows[newRow].Cells[0].Value = itemsMaster[x];
filesFound++;
}
}
}
private bool getFullList(string folderPath)
{
try
{
if (checkBox17.Checked)
itemsMaster = Directory.GetFileSystemEntries(folderPath, "*", SearchOption.AllDirectories);
else
itemsMaster = Directory.GetFileSystemEntries(folderPath, "*", SearchOption.TopDirectoryOnly);
return true;
}
catch (UnauthorizedAccessException e)
{
if(folderPath[folderPath.Length - 1] != '\\')
folderPath += @"\";
if (e.Message == "Access to the path '" + folderPath + "' is denied.")
{
MessageBox.Show("You do not have read permission for the following directory:\n\n\t" + folderPath + "\n\nPlease select another folder or log in as a user with read access to this folder.", "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Error);
folderPath = folderPath.Substring(0, folderPath.Length - 1);
}
else
{
if (accessDenied == null)
accessDenied = new StringBuilder("");
accessDenied.AppendLine(e.Message.Substring(20, e.Message.Length - 32));
}
return false;
}
}
initialPathTB.Text
填充了类似“F:\ COMMON \ Administration”的内容。
这是我的问题。当传递给folderPath
的顶级是用户没有读取权限的顶级时,一切正常。当顶级和所有从属目录是用户已读取访问权限的文件夹时,一切正常。问题在于用户具有对顶级读取权限的目录,但对于某些更深入的子文件夹则不存在。这就是getFullList()
是布尔的原因;如果有任何UnauthorizedAccessExceptions,则itemsMaster
仍为空,SearchFolder()
上numItems = itemsMaster.Length;
失败。
我想要的是itemsMaster
填充folderPath
中的每个项目,只是跳过用户没有读取权限的项目,但我不知道该怎么做没有递归地爬行和检查每个目录。
这段代码比我的旧方法快得多所以我宁愿不完全放弃它。有没有办法让Directory.GetFileSystemEntries()
方法做我想做的事?
答案 0 :(得分:2)
Directory.GetFileSystemEntries(folderPath, "*", SearchOption.AllDirectories).Length
或其他选项(使用此选项时,请记住fullstring
中的前3-5个元素将是您应删除的输出中的垃圾文本:
Process process = new Process();
List<string> fullstring = new List<string>();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += (sender, args2) => fullstring.Add(args2.Data);
process.Start();
process.StandardInput.WriteLine(@"dir /b /s c:\temp | find """" /v");
process.BeginOutputReadLine();
process.WaitForExit(10000); //or whatever is appropriate time
process.Close();
如果您想更好地追踪错误,请进行以下更改:
全局声明List<string> fullstring = new List<string>();
,然后更改OutputDataReceived
的事件处理程序,如下所示:
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
}
static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
try
{
fullstring.Add(e.Data);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
//log exception
}
}
答案 1 :(得分:1)
您写道“我希望进度条能够实际指示程序列表的位置,因此我需要一些项目来将ProgressBar.Maximum属性设置为。”
这是一种特定的愿望,我不确定它在特定情况下是否值得。如果您的ProgressBar(例如)800 px宽,则1个百分点将是0.125px宽。对于“超过十万件物品”的清单 - 让它至少达到100,000件 - 您必须处理8,000件物品才能移动该栏以移动单个像素。您的程序处理8,000件物品需要多长时间?这将有助于您了解您为用户提供的实际反馈。如果花费太长时间,即使它正在工作,它看起来似乎已经挂起了。
如果您希望提供良好的用户反馈,我建议您将ProgressBar的样式设置为Marquee,并提供“现在检查文件# x ”文本指示器。