C# 如何在遍历文件夹树时删除文件
我不确定我做的是否正确,或者我的逻辑是否正确 我正在尝试下一个文件夹结构删除超过一定天数的文件,这部分我已经正确执行,删除空文件夹 所有这些可以在一个循环中完成吗?C# 如何在遍历文件夹树时删除文件,c#,filesystems,delete-file,C#,Filesystems,Delete File,我不确定我做的是否正确,或者我的逻辑是否正确 我正在尝试下一个文件夹结构删除超过一定天数的文件,这部分我已经正确执行,删除空文件夹 所有这些可以在一个循环中完成吗? 我在哪里删除文件夹 我想删除3级或4级以下的空文件夹 private static void TraverseTree(System.IO.DirectoryInfo folder, double days) { Stack<string> dirs = new Stack<stri
我在哪里删除文件夹 我想删除3级或4级以下的空文件夹
private static void TraverseTree(System.IO.DirectoryInfo folder, double days)
{
Stack<string> dirs = new Stack<string>();
if (!folder.Exists)
throw new ArgumentException();
dirs.Push(folder.FullName);
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 (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
string[] files = null;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
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);
Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
// Delete old files
if (fi.LastWriteTime < DateTime.Now.AddDays(-days))
fi.Delete();
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
Console.WriteLine(e.Message);
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);
}
}
private static void TraverseTree(System.IO.DirectoryInfo文件夹,两天)
{
Stack dirs=新堆栈();
如果(!folder.Exists)
抛出新ArgumentException();
dirs.Push(folder.FullName);
而(dirs.Count>0)
{
字符串currentDir=dirs.Pop();
字符串[]子字段;
尝试
{
subDirs=System.IO.Directory.GetDirectories(currentDir);
}
//如果没有,将引发UnauthorizedAccessException异常
//文件夹或文件的发现权限。该权限可能不可接受,也可能不可接受
//忽略异常并继续枚举其余文件和
//DirectoryNotFound异常也是可能的(但不太可能)
//将引发。如果currentDir已被删除,则会发生这种情况
//在我们调用Directory.Exists之后,存在另一个应用程序或线程
//捕获哪些异常的选择完全取决于特定任务
//你打算表演,也取决于你确定知道多少
//关于将在其上运行此代码的系统。
捕获(未经授权的访问例外)
{
控制台写入线(e.Message);
继续;
}
捕获(System.IO.DirectoryNotFounde异常)
{
控制台写入线(e.Message);
继续;
}
string[]files=null;
尝试
{
files=System.IO.Directory.GetFiles(currentDir);
}
捕获(未经授权的访问例外)
{
控制台写入线(e.Message);
继续;
}
捕获(System.IO.DirectoryNotFounde异常)
{
控制台写入线(e.Message);
继续;
}
//在此处对每个文件执行所需操作。
//修改此块以执行所需的任务。
foreach(文件中的字符串文件)
{
尝试
{
//执行场景中需要的任何操作。
System.IO.FileInfo fi=新的System.IO.FileInfo(文件);
WriteLine(“{0}:{1},{2}”,fi.Name,fi.Length,fi.CreationTime);
//删除旧文件
if(fi.LastWriteTime
代码来自。这里有几乎相同的问题:
这是按名称删除,但您可以检查其他属性。递归方法可能更干净
private static void DeleteOldFilesAndFolders(string path)
{
foreach (string directory in System.IO.Directory.GetDirectories(path))
{
DeleteOldFilesAndFolders(directory);
// If the directory is empty and old, delete it here.
}
foreach (string file in System.IO.Directory.GetFiles(path))
{
// Check the file's age and delete it if it's old.
}
}
对于这个问题,您将看到一个以IEnumerable非递归方式实现的文件系统walker
对此,您的解决方案可能可以实现为:
List<string> directoriesToDelete = new List<string>();
DirectoryWalker walker = new DirectoryWalker(@"C:\pathToSource\src",
dir => {
if (Directory.GetFileSystemEntries(dir).Length == 0) {
directoriesToDelete.Add(dir);
return false;
}
return true;
},
file => {
if (FileIsTooOld(file)) {
return true;
}
return false;
}
);
foreach (string file in walker)
File.Delete(file);
foreach (string dir in directoriesToDelete)
Directory.Delete(dir);
List directoriesToDelete=new List();
DirectoryWalker=新的DirectoryWalker(@“C:\pathToSource\src”,
目录=>{
if(Directory.GetFileSystemEntries(dir).Length==0){
directoriesToDelete.Add(dir);
返回false;
}
返回true;
},
文件=>{
如果(文件工具(文件)){
返回true;
}
返回false;
}
);
foreach(walker中的字符串文件)
文件。删除(文件);
foreach(directoriesToDelete中的字符串dir)
目录.删除(dir);
我注意到,关于您的代码,数十行用于遍历树结构的“机制”完全压倒了实际执行工作的两行代码。这使得阅读、理解、更改、调试和维护这些代码变得困难
以下是我将要做的
程序中只有三个高级操作:(1)获取所有文件,(2)筛选以查找要删除的文件,(3)删除每个文件。因此,编写一个程序,在一条语句中执行这些操作
对于第一个操作,我将把上面的机制分解成它自己的函数:一个实现(比如)IEnumerable的函数,它所做的只是不断地产生关于文件的信息。它与它们没有任何关系;它唯一的目的就是不断地发布文件信息
一旦有了这种机制,就可以开始在该序列之上编写查询,以实现第二个操作。第三个操作直接从第二个操作开始
简言之,程序的主线应如下所示:
var allFiles = TraverseFolder(folder);
var filesToDelete = from file in allFiles where IsOld(file) select file;
foreach(var fileToDelete in filesToDelete) Delete(fileToDelete);
清楚吗?我增强了功能,实现了缺失代码、错误处理和检查:
/* Given a directory path and a datetime,
* recursively delete all files and directories contained in such directory
* (given directory included) that are younger than the given date.
*/
private bool DeleteDirectoryTree(string dir, DateTime keepFilesYoungerThan)
{
//checks
if (String.IsNullOrEmpty(dir) || !Directory.Exists(dir))
return false;
//recurse on children directories
foreach (string childDir in Directory.GetDirectories(dir))
DeleteDirectoryTree(childDir, keepFilesYoungerThan);
//loop on children files
foreach (string file in Directory.GetFiles(dir))
{
//calculate file datetime
DateTime fileDT = new DateTime(Math.Max(File.GetCreationTime(file).Ticks, File.GetLastWriteTime(file).Ticks));
//if file is old, delete it
if (fileDT <= keepFilesYoungerThan)
try
{
File.Delete(file);
Log("Deleted file " + file);
}
catch (Exception e)
{
LogError("Could not delete file " + file + ", cause: " + e.Message);
}
}
//if this directory is empty, delete it
if (!Directory.EnumerateFileSystemEntries(dir).Any())
try
{
Directory.Delete(dir);
Log("Deleted directory " + dir);
}
catch (Exception e)
{
LogError("Could not delete directory " + dir + ", cause: " + e.Message);
}
return true;
}
/*给定目录路径和日期时间,
*递归删除该目录中包含的所有文件和目录
*(包括给定目录)比给定日期早。
*/
私有bool DeleteDirectoryTree(字符串目录,Dat