反正有没有在C#中获取所有文件名而没有例外?

时间:2012-12-14 20:48:57

标签: c#

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

在目录中有许多枚举文件的方法,但都遇到了同样的问题:

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

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

即使在管理员,单用户计算机下运行,似乎也无法列出所有文件而不会遇到异常\错误。

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

标题为“Enumerate Directories and Files”的

This link from MS没有显示如何枚举目录和文件,它只显示了不会抛出的内容的一部分:DirectoryNotFoundException,UnauthorizedAccessException,PathTooLongException,

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

只需查看“错误{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);
    }

    }
}

1 个答案:

答案 0 :(得分:6)

是的,至少很难枚举所有文件而没有例外。

这里有几个问题:

  • CLR不支持某些路径(长路径-PathTooLongException)
  • 文件夹/文件的安全限制
  • 引入重复项的结点/硬链接(在理论上循环到递归迭代中的StackOverflow)。
  • 基本共享违规限制(如果您尝试读取文件)。

对于PathTooLongException:我认为你需要处理相应Win32函数的PInvoke。 CLR中所有与路径相关的方法都限制为256个字符。

安全限制 - 如果您在系统(不确定)下运行或具有备份权限,您可能能够枚举所有内容,但保证任何其他帐户无法访问默认配置的系统上的所有文件。 您可以PInvoke本机版本并处理错误代码,而不是获得异常。您可以通过直接检查ACL来减少进入目录的异常数量。