在C#中是否仍然可以毫无例外地获取所有文件名?
更新:我很高兴放弃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”日志文件,查看管理员无法访问的位置有多少在C#中是否仍然可以毫无例外地获取所有文件名?,c#,C#,更新:我很高兴放弃C#要求,只要看到任何程序可以列出所有以管理员或系统身份运行的文件,我的问题是有人见过这样的事情吗 枚举目录中文件的方法有很多,但都有相同的问题: 指定的路径、文件名或两者都太长。完全限定的文件名必须少于260个字符,目录名必须少于248个字符 “对路径“C:\Users\All Users\Application Data”的访问被拒绝” 等等 即使在管理员、单用户机器下运行,似乎也不可能列出所有文件而不遇到异常\错误 仅仅获取windows下所有文件的列表真的是一项不可能的
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)
- 文件夹/文件的安全限制
- 引入重复项的连接/硬链接(理论上是递归迭代中堆栈溢出的循环)
- 基本共享冲突限制(如果您尝试读取文件)