我正在尝试使用DirectoryInfo.GetDirectories()
查找给定路径下的每个目录。
问题是它似乎工作正常,当UnauthorizedAccess Exception
尝试从System Volume Information
读取时,除using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace WolfPaw_Duplicate_Search_and_Destroy
{
class FindDirectories
{
DirectoryInfo[] tempDirectoryInfo;
DirectoryInfo[] fullDirectoryInfo;
String tmpDirInfo = "";
String tmpDirInfo2 = "";
String[] fullDirInfo = new String[1000000];
DirectoryInfo[] dinf = new DirectoryInfo[100];
public DirectoryInfo[] getDirectories(DirectoryInfo[] dinf)
{
tempDirectoryInfo = dinf;
GetDirectories();
return fullDirectoryInfo;
}
private void GetDirectories()
{
try
{
int index = 0;
try
{
foreach (DirectoryInfo dinf in tempDirectoryInfo)
{
if (dinf != null)
foreach (DirectoryInfo dd in dinf.GetDirectories())
{
if (dd != null)
{
tmpDirInfo += dd.FullName + "♣";
index++;
}
}
}
}
catch(Exception ex) { MessageBox.Show("Current working directories: " + tmpDirInfo + Environment.NewLine + "Error Message: " + ex.Message); }
tmpDirInfo2 += tmpDirInfo;
tempDirectoryInfo = new DirectoryInfo[index];
index = 0;
foreach (String s in tmpDirInfo.Split('♣'))
{
if (s.Length > 0)
tempDirectoryInfo[index] = new DirectoryInfo(s);
index++;
}
tmpDirInfo = "";
int i = 0;
foreach (DirectoryInfo x in tempDirectoryInfo)
{
if (x != null)
i++;
}
if (tempDirectoryInfo.Length != 0)
{
GetDirectories();
}
else
{
StringToDirInfo(tmpDirInfo2);
}
}
catch (UnauthorizedAccessException)
{ }
catch (Exception)
{
throw;
}
}
private void StringToDirInfo(String s_dInfo)
{
int index = 0;
foreach (String s in s_dInfo.Split('♣'))
{
index++;
}
fullDirectoryInfo = new DirectoryInfo[index];
index = 0;
foreach (String s in s_dInfo.Split('♣'))
{
if (s.Length > 0)
{
fullDirectoryInfo[index] = new DirectoryInfo(s);
index++;
}
}
}
}
}
之外没有任何错误,但仍然在它缺少目录的所有内容的末尾。
根据TotalCMD(使用属性选项)我的D:\ Drive有4580个目录,根据Windows资源管理器它有4574个,根据我的程序它有4566个...
我已经尝试了我能想到的一切。逐个检查DIR-s,清空回收站,包括手动隐藏目录,但似乎没有任何区别。还有,不只是在我的D盘上......
这是一个常见的错误还是有原因?
(刚提到我自己完全学习c#所以我的做法可能完全错了,这就是我如何通过我还不知道的事情)
编辑:我的所有代码:
FindDirectories.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;
using System.IO;
namespace WolfPaw_Duplicate_Search_and_Destroy
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
foreach(String s in Environment.GetLogicalDrives())
{
DriveInfo dinf1 = new DriveInfo(s);
try
{
if(dinf1.DriveType != DriveType.CDRom)
{
textBox_Dirs.Text += s + "||";
}
}
catch { }
}
comboBox_Larger.SelectedIndex = 0;
comboBox_Smaller.SelectedIndex = 0;
}
private void button_DirResize_Click(object sender, EventArgs e)
{
if (textBox_Dirs.Height < 100)
{
textBox_Dirs.Height = 100;
textBox_Dirs.Multiline = true;
button_DirResize.Top = textBox_Dirs.Bottom - (button_DirResize.Height / 2);
}
else
{
textBox_Dirs.Height = 20;
textBox_Dirs.Multiline = false;
button_DirResize.Top = textBox_Dirs.Bottom - (button_DirResize.Height / 2);
}
textBox_FileTypes.Top = textBox_Dirs.Bottom + 15;
comboBox_Filetypes.Top = textBox_FileTypes.Top;
label_FyleType.Top = textBox_FileTypes.Top + ((textBox_FileTypes.Height / 2) - (label_FyleType.Height / 2));
button_FileTypeResize.Top = textBox_FileTypes.Bottom - (button_FileTypeResize.Height / 2);
}
private void comboBox_Filetypes_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox_Filetypes.SelectedItem.ToString().Contains("*.*") == false)
{
if (textBox_FileTypes.Text.Contains("*.*; "))
{
textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("*.*; ", "");
}
else if (textBox_FileTypes.Text.Contains("*.*;"))
{
textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("*.*;", "");
}
else if (textBox_FileTypes.Text.Contains("*.*"))
{
textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("*.*", "");
}
}
textBox_FileTypes.Text += comboBox_Filetypes.SelectedItem.ToString().Substring(comboBox_Filetypes.SelectedItem.ToString().IndexOf("(") + 1).Replace(")","") + "; ";
}
private void textBox_FileTypes_TextChanged(object sender, EventArgs e)
{
if(textBox_FileTypes.Text.Contains("*.*"))
{
textBox_FileTypes.Text = "*.*;";
}
else if(textBox_FileTypes.Text.Contains("; ; "))
{
textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("; ; ","; ");
}
else if (textBox_FileTypes.Text.Contains(";; "))
{
textBox_FileTypes.Text = textBox_FileTypes.Text.Replace(";; ", "; ");
textBox_FileTypes.SelectionStart = textBox_FileTypes.Text.Length;
textBox_FileTypes.Select();
}
}
private void button_FileTypeResize_Click(object sender, EventArgs e)
{
if (textBox_FileTypes.Height < 100)
{
textBox_FileTypes.Height = 100;
textBox_FileTypes.Multiline = true;
button_FileTypeResize.Top = textBox_FileTypes.Bottom - (button_FileTypeResize.Height / 2);
}
else
{
textBox_FileTypes.Height = 20;
textBox_FileTypes.Multiline = false;
button_FileTypeResize.Top = textBox_FileTypes.Bottom - (button_FileTypeResize.Height / 2);
label_FyleType.Top = textBox_FileTypes.Top + ((textBox_FileTypes.Height / 2) - (label_FyleType.Height / 2));
}
textBox_FileTypes.Top = textBox_Dirs.Bottom + 15;
comboBox_Filetypes.Top = textBox_FileTypes.Top;
}
private void button1_Click(object sender, EventArgs e)
{
if (label_FileBeingChecked.Height < 100)
{
label_FileBeingChecked.Height = 100;
button1.Text = "↑";
button1.Cursor = Cursors.PanNorth;
}
else
{
label_FileBeingChecked.Height = 24;
button1.Text = "↓";
button1.Cursor = Cursors.PanSouth;
}
progressBar1.Top = label_FileBeingChecked.Bottom + 2;
label_FNumber.Top = progressBar1.Bottom + 4;
label_NumOfFiles.Top = progressBar1.Bottom + 4;
}
private void button_Browse_Click(object sender, EventArgs e)
{
FolderBrowserDialog ofd = new FolderBrowserDialog();
DialogResult dres = ofd.ShowDialog();
if(dres == System.Windows.Forms.DialogResult.OK)
{
textBox_Dirs.Text += ofd.SelectedPath + "||";
}
}
private void button_Start_Click(object sender, EventArgs e)
{
StartSearch();
}
public void StartSearch()
{
//Get Directory List
FindDirectories fd = new FindDirectories();
int index = 0;
String[] s_Dirs = textBox_Dirs.Text.Replace("||","↓").Split('↓');
DirectoryInfo[] di = new DirectoryInfo[s_Dirs.Length];
foreach(String s in s_Dirs)
{
if(s.Length != 0)
di[index] = new DirectoryInfo(s);
index++;
}
DirectoryInfo[] dinfo = fd.getDirectories(di);
int xx = 0;
String testStr = "";
foreach (DirectoryInfo d in dinfo)
{
if (d != null)
{
//testStr += d.Root + " | " + d.Parent + " | " + d.FullName + "♣";
xx++;
}
}
//testStr += "♣♣ # of Directories found:" + xx;
//File.WriteAllText(@"C:\t.txt",testStr.Replace("♣",Environment.NewLine));
MessageBox.Show(xx.ToString());
}
}
}
Form1.cs的
{{1}}
答案 0 :(得分:1)
我要跳枪并假设您首先要获取给定路径下的所有目录的单个列表(递归)。这段代码应该这样做:
string[] allDirs = Directory.GetDirectories(@"D:\", "*.*", SearchOption.AllDirectories);
或者如果您需要基于模式的所有文件,请使用:
string[] allFiles = Directory.GetFiles(@"D:\", "*.*", SearchOption.AllDirectories);
修改强>
如果您遇到UnauthorizedAccessException
问题,可以使用LINQ和递归来推送自己的实现,例如:
private static IEnumerable<string> MyGetDirectories(string basePath)
{
try
{
string[] dirs = Directory.GetDirectories(basePath);
return dirs.Union(dirs.SelectMany(dir => MyGetDirectories(dir)));
}
catch(UnauthorizedAccessException)
{
return Enumerable.Empty<string>();
}
}
您可以使用以下内容调用(并转回数组):
string[] allDirs = MyGetDirectories(@"D:\").ToArray();
支持多个基本路径
如果你有一个包含多个基本路径的数组,我们可以再次使用SelectMany
将所有内容放在一个列表中,所以:
string[] basePaths = new string[] { @"C:\", @"D:\" };
string[] allDirs = basePaths.SelectMany(dir => MyGetDirectories(dir)).ToArray();
这意味着对于basePaths
中的每个项目,我们将使用该条目来选择许多匹配的项目(在这种情况下通过调用MyGetDirectories
)然后将所有内容连接成一个大项目名单。在最后一步中,它将转换回数组。