我不确定我是否正确地执行此操作,或者我的逻辑是否正确。
我正在尝试删除一个文件夹结构,删除早于一定天数的文件,这部分我已经正确实现,删除空文件夹。
这一切都可以在一个循环中完成吗? 我在哪里删除文件夹?
我想删除最多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);
}
}
代码来自MSDN。
答案 0 :(得分:5)
递归方法可能更清晰。
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.
}
}
答案 1 :(得分:3)
我注意到你的代码的一些事情是,用于遍历树结构的几十行“机制”完全压倒了实际完成工作的两行代码。这使得难以阅读,理解,更改,调试和维护此代码。
这就是我要做的事情。
您的程序中只有三个高级操作:(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);
这是清楚的吗?
答案 2 :(得分:0)
答案 3 :(得分:0)
Here is a more general solution问题,它为您提供了一个非递归地实现为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);
答案 4 :(得分:0)
我增强了John's solution,实现了缺失的代码,错误处理和检查:
/* 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;
}