我有以下代码,它找到并显示空文件夹,遗憾的是它无法处理所有文件夹,回收站和应用程序数据文件夹导致访问异常。
再往下是来自另一个使用枚举的用户的示例,有了它我可以访问受限制的文件夹,但它无法处理长路径。
我正在尝试Delimon.Win32.IO;来自http://gallery.technet.microsoft.com/scriptcenter/DelimonWin32IO-Library-V40-7ff6b16c的命名空间它显然可以处理长路径(我还没有测试过它)
我需要一个可以处理访问限制和长路径的解决方案 - 如果可能的话。
private void button1_Click(object sender, EventArgs e)
{
//Open folder browser for user to select the folder to scan
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
//Clear text fields
listBoxResults.Items.Clear();
listBoxPath.Items.Clear();
txtFoldersFound.Clear();
//Store selected folder path
string dirPath = folderBrowserDialog1.SelectedPath;
//Process the folder
try
{
foreach (string dir in Directory.GetDirectories(dirPath, "*.*", SearchOption.AllDirectories))
{
//Populate List Box with all folders found
this.Invoke(new Action(() => listUpdate2(dir)));
if (Directory.GetDirectories(dir).Length.Equals(0))
{
//Populate List Box with all empty folders found
this.Invoke(new Action(() => listUpdate1(dir + Environment.NewLine)));
}
}
//Count of the empty folders
txtFoldersFound.Text = listBoxResults.Items.Count.ToString();
}
//Catch exceptions, seems to be folders not accessible causing this. Recycle Bin, App Data etc
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
}
答案 0 :(得分:0)
似乎枚举目录仍然是.NET 4.5中的一个问题:
提供的代码使用递归来遍历目录结构。
private void button1_Click(object sender, EventArgs e)
{
//Open folder browser for user to select the folder to scan
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
//Clear text fields
listBoxResults.Items.Clear();
listBoxPath.Items.Clear();
txtFoldersFound.Clear();
//Store selected folder path
string dirPath = folderBrowserDialog1.SelectedPath;
Action<string> performOnEachFolder = (s) => this.Invoke(new Action(() => listUpdate2(s)));
foreach (string emptyFolder in GetAllEmptyFolders(dirPath, performOnEachFolder))
this.Invoke(new Action(() => listUpdate2(emptyFolder)));
}
}
private static IEnumerable<string> GetAllEmptyFolders(string path, Action<string> performOnEachFolder)
{
performOnEachFolder(path);
EmptyResult result = IsDirectoryEmpty(path);
if (result == EmptyResult.Empty)
yield return path;
if (result == EmptyResult.Error)
yield break;
//A reparse point may indicate a recursive file structure. Cause this to stop the recursion.
//http://blogs.msdn.com/b/oldnewthing/archive/2004/12/27/332704.aspx
if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
yield break;
IEnumerator<string> it = Directory.EnumerateDirectories(path, "*.*", SearchOption.TopDirectoryOnly).GetEnumerator();
while (it.MoveNext())
{
foreach (string emptyFolder in GetAllEmptyFolders(it.Current, performOnEachFolder))
{
yield return emptyFolder;
}
}
}
private enum EmptyResult
{
Empty = 1,
Used = 2,
Error = 3
}
private static EmptyResult IsDirectoryEmpty(string path)
{
try
{
return !Directory.EnumerateFileSystemEntries(path).Any() ? EmptyResult.Empty : EmptyResult.Used;
}
catch (UnauthorizedAccessException)
{
//We do not want the method to throw as that will cause problems with the iterator block.
return EmptyResult.Error;
}
}