访问路径';d: $RECYCLE.BINS-5-21-494745725-312220573-77495
本文关键字:RECYCLE BINS-5-21-494745725-312220573-77495 路径 访问 | 更新日期: 2023-09-27 18:28:24
我是C#的新手。我有一个文本框,我在其中输入要搜索的文件和一个"搜索"按钮。在搜索的时候,我希望它填充文件夹中的文件,但我得到了上面的错误。以下是我的代码:
string[] directories = Directory.GetDirectories(@"d:'",
"*",
SearchOption.AllDirectories);
string file = textBox1.Text;
DataGrid dg = new DataGrid();
{
var files = new List<string>();
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady))
{
try
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, file , SearchOption.AllDirectories));
}
catch(Exception ex)
{
MessageBox.Show("the exception is " + ex.ToString());
//Logger.Log(e.Message); // Log it and move on
}
}
请帮我解决。感谢
在可能包含不可访问子文件夹的文件夹上搜索时,最重要的规则是:
不要使用
SearchOption.AllDirectories
!
请改用SearchOption.TopDirectoryOnly
,并结合对所有可访问目录的递归搜索。
使用SearchOption.AllDirectories
,一次访问冲突将破坏整个循环,甚至在处理任何文件/目录之前。但如果使用SearchOption.TopDirectoryOnly
,则只跳过无法访问的内容。
有一种更困难的方法可以使用Directory.GetAccessControl()
每个子目录检查来查看您是否有权提前访问目录(尽管此选项相当困难-除非您确切了解访问系统的工作方式,否则我不建议您这样做)。
对于递归搜索,我实现了以下代码供自己使用:
public static List<string> GetAllAccessibleDirectories(string path, string searchPattern) {
List<string> dirPathList = new List<string>();
try {
List<string> childDirPathList = Directory.GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly).ToList(); //use TopDirectoryOnly
if (childDirPathList == null || childDirPathList.Count <= 0) //this directory has no child
return null;
foreach (string childDirPath in childDirPathList) { //foreach child directory, do recursive search
dirPathList.Add(childDirPath); //add the path
List<string> grandChildDirPath = GetAllAccessibleDirectories(childDirPath, searchPattern);
if (grandChildDirPath != null && grandChildDirPath.Count > 0) //this child directory has children and nothing has gone wrong
dirPathList.AddRange(grandChildDirPath.ToArray()); //add the grandchildren to the list
}
return dirPathList; //return the whole list found at this level
} catch {
return null; //something has gone wrong, return null
}
}
这就是你所说的
List<string> accessibleDirs = GetAllAccessibleDirectories(myrootpath, "*");
然后,您只需要在所有可访问的目录中搜索/添加文件。
注意:这个问题非常经典。我相信还有其他更好的解决方案。
如果在获得所有可访问的目录后,有一些目录是您特别想要避免的,您也可以使用目录名称的一部分作为关键字(即Recycle.Bins
)通过LINQ过滤List
结果。
正如Ian在他的文章中所指出的,在类似于您的情况下,不要使用递归文件列表(Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories)
),因为第一个异常将停止进一步处理。
此外,为了在一定程度上缓解这些问题并获得更好的结果,您应该将此程序作为Administrator
运行。这可以通过在windows资源管理器中右键单击应用程序,然后选中Compatibility
选项卡上的Run this program as an administrator
选项来完成。
此外,您应该使用下面这样的代码来进行搜索,这样中间的异常不会停止进一步的搜索。
static void Main(string[] args) {
string fileToFind = "*.jpg";
var files = new List<string>();
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady))
files.AddRange(FindDirectory(fileToFind, d.RootDirectory.FullName));
}
/// <summary>
/// This function returns the full file path of the matches it finds.
/// 1. It does not do any parameter validation
/// 2. It searches recursively
/// 3. It eats up any error that occurs when requesting files and directories within the specified path
/// 4. Supports specifying wildcards in the fileToFind parameter.
/// </summary>
/// <param name="fileToFind">Name of the file to search, without the path</param>
/// <param name="path">The path under which the file needs to be searched</param>
/// <returns>Enumeration of all valid full file paths matching the file</returns>
public static IEnumerable<string> FindDirectory(string fileToFind, string path) {
// Check if "path" directly contains "fileToFind"
string[] files = null;
try {
files = Directory.GetFiles(path, fileToFind);
} catch { }
if (files != null) {
foreach (var file in files)
yield return file;
}
// Check all sub-directories of "path" to see if they contain "fileToFInd"
string[] subDirs = null;
try {
subDirs = Directory.GetDirectories(path);
} catch { }
if (subDirs == null)
yield break;
foreach (var subDir in subDirs)
foreach (var foundFile in FindDirectory(fileToFind, subDir))
yield return foundFile;
}