PDA

View Full Version : مقاله: بازیابی لیست فایلها و پوشه ها با DirectoryInfo



Saeed_m_Farid
سه شنبه 06 مرداد 1388, 14:36 عصر
سلام
قبل همه چیز، باید بگم پستی که دارم میزنم یه article تو CodeProject (http://www.codeproject.com/Articles/38258/How-to-Get-a-List-of-Files-and-Folders-Without-Directory-GetFiles-Access-Denied-Error.aspx) توسط merlin981 (http://www.codeproject.com/Members/merlin981) بود که مشکل من رو حل کرد؛ گفتم شاید بدرد دوستان بخوره، اینجا آوردمش :

همونطوری که میدونید، برای بازیابی لیست فایلها و پوشه ها میشه از Directory.GetFiles و Directory.GetDirectories استفاده کرد، ولی تو ویندوز ویستا و ویندوز 7 برای بعضی از پوشه ها Access Denied میده (از جمله پوشه "Users") و لیستی بر نمی گرده.

علت این امر اینه که در ویندوز ویستا و ویندوز 7؛ اکثر از پوشه های زیرمجموعه پوشه Users، اجازه دسترسی ACL (http://en.wikipedia.org/wiki/Access_control_list)ای که سیستم عامل برای پوشه موردنظر قائل میشه، مانع از Reading یا Browsing میشه.
تو این مثال از شیء DirectoryInfo برای بدست آوردن لیست پوشه ها تو یه حلقه تا پایانشون استفاده میشه. البته باید توجه کنید که در این مثال برای بهره گیری از قابلیت multi-threading حلقه ها، از PLINQ - Parallel LINQ استفاده شده؛ اگه PLINQ رو سیستم تون نصب نیست کافیه Parallel.ForEach(ها) رو به ForEach معمولی تبدیل کنید :


using System;
using System.IO;
using System.Threading;

namespace MStaller
{
internal static class DirectoryListing
{
#region DirectoryList

/// <summary>
/// Returns a list of directories under RootDirectory
/// </summary>
/// <param name="RootDirectory">starting directory</param>
/// <param name="SearchAllDirectories">when true, all sub directories
/// will be searched as well</param>
/// <param name="Filter">filter to be done on directory. use null for no
/// filtering</param>
public static List<string> DirectoryList(string RootDirectory,
bool SearchAllDirectories, Predicate<string> Filter)
{
List<string> retList = new List<string>();

try
{
// create a directory info object
DirectoryInfo di = new DirectoryInfo(RootDirectory);

// loop through directories populating the list
Parallel.ForEach(di.GetDirectories(), folder =>
{
try
{
// add the folder if it passes the filter
if ((Filter == null) || (Filter(folder.FullName)))
{
// add the folder
retList.Add(folder.FullName);

// get it's sub folders
if (SearchAllDirectories)
retList.AddRange(DirectoryList(folder.FullName, true,
Filter));
}
}

catch (UnauthorizedAccessException)
{
// don't really need to do anything
// user just doesn't have access
}

catch (Exception excep)
{
// TODO: log the exception
}
});
}

catch (Exception excep)
{
// TODO: save exception
}

// return the list
return retList;
}

// DirectoryList
#endregion

#region FileList

/// <summary>
/// Returns a list of files under RootDirectory
/// </summary>
/// <param name="RootDirectory">starting directory</param>
/// <param name="SearchAllDirectories">when true, all sub directories will
/// be searched as well</param>
/// <param name="Filter">filter to be done on files/directory. use null for no
/// filtering</param>
public static List<string> FileList(string RootDirectory,
bool SearchAllDirectories, Predicate<string> Filter)
{
List<string> retList = new List<string>();

try
{
// get the list of directories
List<string> DirList = new List<string> { RootDirectory };

// get sub directories if allowed
if (SearchAllDirectories)
DirList.AddRange(DirectoryList(RootDirectory, true, null));

// loop through directories populating the list
Parallel.ForEach(DirList, folder =>
{
// get a directory object
DirectoryInfo di = new DirectoryInfo(folder);

try
{
// loop through the files in this directory
foreach (FileInfo file in di.GetFiles())
{
try
{
// add the file if it passes the filter
if ((Filter == null) || (Filter(file.FullName)))
retList.Add(file.FullName);
}

catch (Exception excep)
{
// TODO: log the exception
}
}
}

catch (UnauthorizedAccessException)
{
// don't really need to do anything
// user just doesn't have access
}

catch (Exception excep)
{
// TODO: log the exception
}
});
}

catch (Exception excep)
{
// TODO: save exception
}

// return the list
return retList;
}

// FileList
#endregion
}
}