在C#中是否仍然可以毫无例外地获取所有文件名?

在C#中是否仍然可以毫无例外地获取所有文件名?,c#,C#,更新:我很高兴放弃C#要求,只要看到任何程序可以列出所有以管理员或系统身份运行的文件,我的问题是有人见过这样的事情吗 枚举目录中文件的方法有很多,但都有相同的问题: 指定的路径、文件名或两者都太长。完全限定的文件名必须少于260个字符,目录名必须少于248个字符 “对路径“C:\Users\All Users\Application Data”的访问被拒绝” 等等 即使在管理员、单用户机器下运行,似乎也不可能列出所有文件而不遇到异常\错误 仅仅获取windows下所有文件的列表真的是一项不可能的

更新:我很高兴放弃C#要求,只要看到任何程序可以列出所有以管理员或系统身份运行的文件,我的问题是有人见过这样的事情吗

枚举目录中文件的方法有很多,但都有相同的问题:

指定的路径、文件名或两者都太长。完全限定的文件名必须少于260个字符,目录名必须少于248个字符

“对路径“C:\Users\All Users\Application Data”的访问被拒绝”

等等

即使在管理员、单用户机器下运行,似乎也不可能列出所有文件而不遇到异常\错误

仅仅获取windows下所有文件的列表真的是一项不可能的任务吗?是否有人能够使用C#或任何其他方法获得机器上所有文件的完整列表

标题为“Enumerate directory and Files”(枚举目录和文件)不显示如何枚举目录和文件,它只显示不会抛出的内容的子集:DirectoryNotFoundException、UnauthorizedAccessException、PathTooLongException、

更新:下面是在C上运行并尝试枚举所有文件和错误的示例代码。即使以管理员身份运行,也有一些文件夹不仅可以访问,而且我甚至不能将它们的所有权更改为管理员!例如:“C:\Windows\CSC”

只需查看“Errors{0}.csv”日志文件,查看管理员无法访问的位置有多少

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;


class Program
{

static System.IO.StreamWriter logfile;
static System.IO.StreamWriter errorfile;
static void Main(string[] args)
{
    string directory = @"C:\";

    logfile = new System.IO.StreamWriter(string.Format(@"E:\Files {0}.csv", DateTime.Now.ToString("yyyyMMddHHmm")));
    errorfile = new System.IO.StreamWriter(string.Format(@"E:\Errors {0}.csv", DateTime.Now.ToString("yyyyMMddHHmm")));
    TraverseTree(directory, OnGotFileInfo, OnGotException);

    logfile.Close();
    errorfile.Close(); 
}

public static void OnGotFileInfo(System.IO.FileInfo fileInfo)
{
    logfile.WriteLine("{0},{1},", fileInfo.FullName, fileInfo.Length.ToString("N0"));
}

public static void OnGotException(Exception ex, string info)
{
    errorfile.WriteLine("{0},{1}", ex.Message, info);
}

public static void TraverseTree(string root, Action<System.IO.FileInfo> fileAction, Action<Exception, string> errorAction)
{
    // Data structure to hold names of subfolders to be 
    // examined for files.
    Stack<string> dirs = new Stack<string>(20);

    if (!System.IO.Directory.Exists(root))
    {
        throw new ArgumentException();
    }
    dirs.Push(root);

    while (dirs.Count > 0)
    {
        string currentDir = dirs.Pop();
        string[] subDirs;
        try
        {
            subDirs = System.IO.Directory.GetDirectories(currentDir);
        }
        // An UnauthorizedAccessException exception will be thrown if we do not have 
        // discovery permission on a folder or file. It may or may not be acceptable  
        // to ignore the exception and continue enumerating the remaining files and  
        // folders. It is also possible (but unlikely) that a DirectoryNotFound exception  
        // will be raised. This will happen if currentDir has been deleted by 
        // another application or thread after our call to Directory.Exists. The  
        // choice of which exceptions to catch depends entirely on the specific task  
        // you are intending to perform and also on how much you know with certainty  
        // about the systems on which this code will run. 

        catch (System.Exception e)
        {
            errorAction(e, currentDir);
            continue;
        }

        string[] files = null;
        try
        {
            files = System.IO.Directory.GetFiles(currentDir);
        }

        catch (System.Exception e)
        {
            errorAction(e, currentDir);
            continue;
        }

        // Perform the required action on each file here. 
        // Modify this block to perform your required task. 
        foreach (string file in files)
        {
            try
            {
                // Perform whatever action is required in your scenario.
                System.IO.FileInfo fi = new System.IO.FileInfo(file);
                fileAction(fi);
            }
            catch (System.Exception e)
            {
                // If file was deleted by a separate application 
                //  or thread since the call to TraverseTree() 
                // then just continue.
                errorAction(e ,file);
                continue;
            }
        }

        // Push the subdirectories onto the stack for traversal. 
        // This could also be done before handing the files. 
        foreach (string str in subDirs)
            dirs.Push(str);
    }

    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
班级计划
{
静态System.IO.StreamWriter日志文件;
静态System.IO.StreamWriter错误文件;
静态void Main(字符串[]参数)
{
字符串目录=@“C:\”;
logfile=new System.IO.StreamWriter(string.Format(@“E:\Files{0}.csv”,DateTime.Now.ToString(“yyyyMMddHHmm”));
errorfile=new System.IO.StreamWriter(string.Format(@“E:\Errors{0}.csv”,DateTime.Now.ToString(“yyyyMMddHHmm”));
TraverseTree(目录、OnGotFileInfo、OnGotException);
logfile.Close();
errorfile.Close();
}
公共静态void OnGotFileInfo(System.IO.FileInfo FileInfo)
{
logfile.WriteLine(“{0},{1},”,fileInfo.FullName,fileInfo.Length.ToString(“N0”);
}
公共静态void OnGotException(异常示例,字符串信息)
{
errorfile.WriteLine(“{0},{1}”,例如Message,info);
}
publicstaticvoidtraversetree(stringroot、actionfileaction、actionerroraction)
{
//用于保存要删除的子文件夹名称的数据结构
//检查文件。
堆栈dirs=新堆栈(20);
如果(!System.IO.Directory.Exists(root))
{
抛出新ArgumentException();
}
直接推力(根);
而(dirs.Count>0)
{
字符串currentDir=dirs.Pop();
字符串[]子字段;
尝试
{
subDirs=System.IO.Directory.GetDirectories(currentDir);
}
//如果没有,将引发UnauthorizedAccessException异常
//文件夹或文件的发现权限。该权限可能不可接受,也可能不可接受
//忽略异常并继续枚举其余文件和
//DirectoryNotFound异常也是可能的(但不太可能)
//将引发。如果currentDir已被删除,则会发生这种情况
//在我们调用Directory.Exists之后,存在另一个应用程序或线程
//捕获哪些异常的选择完全取决于特定任务
//你打算表演,也取决于你确定知道多少
//关于将在其上运行此代码的系统。
捕获(System.e例外)
{
错误动作(e,currentDir);
继续;
}
string[]files=null;
尝试
{
files=System.IO.Directory.GetFiles(currentDir);
}
捕获(System.e例外)
{
错误动作(e,currentDir);
继续;
}
//在此处对每个文件执行所需操作。
//修改此块以执行所需的任务。
foreach(文件中的字符串文件)
{
尝试
{
//执行场景中需要的任何操作。
System.IO.FileInfo fi=新的System.IO.FileInfo(文件);
文件行动(fi);
}
捕获(System.e例外)
{
//如果文件被单独的应用程序删除
//或自调用TraverseTree()以来的线程
//那就继续吧。
错误行动(e,文件);
继续;
}
}
//将子目录推到堆栈上进行遍历。
//这也可以在移交文件之前完成。
foreach(子目录中的字符串str)
直接推力(str);
}
}
}

是的,至少很难无例外地枚举所有文件

这里有几组问题:

  • CLR不支持某些路径(长路径-PathTooLongException)
  • 文件夹/文件的安全限制
  • 引入重复项的连接/硬链接(理论上是递归迭代中堆栈溢出的循环)
  • 基本共享冲突限制(如果您尝试读取文件)
对于PathTooLongException:我认为您需要处理相应Win32函数的PInvoke。CLR中所有与路径相关的方法的长度限制为256个字符

安全限制-如果您在系统(不确定)下运行或具有备份权限,则可以枚举所有内容,但任何其他帐户都保证无法访问默认配置的系统上的所有文件。 您可以使用PInvoke本机版本并处理错误代码,而不是获取异常。您可以在进入direc时减少异常的数量