C# 如何删除所有文件/文件夹,但将根文件夹保留在C中#
我写了一些代码来递归删除.Net中的所有文件/文件夹,它可以正常工作,但我想保留根文件夹。有没有办法修改文件夹删除条件(Directory.GetFiles(sPath).Length==0&&Directory.GetDirectories(sPath).Length==0)以知道它是根文件夹,即使根文件夹中没有文件/文件夹,也不删除它C# 如何删除所有文件/文件夹,但将根文件夹保留在C中#,c#,.net,C#,.net,我写了一些代码来递归删除.Net中的所有文件/文件夹,它可以正常工作,但我想保留根文件夹。有没有办法修改文件夹删除条件(Directory.GetFiles(sPath).Length==0&&Directory.GetDirectories(sPath).Length==0)以知道它是根文件夹,即使根文件夹中没有文件/文件夹,也不删除它 void CleanupFiles(String sPath, int iDayDelAge) { if (iDayDelAge != 0) // e
void CleanupFiles(String sPath, int iDayDelAge)
{
if (iDayDelAge != 0) // enabled?
{
// Check for aged files to remove
foreach (String file in Directory.GetFiles(sPath))
{
FileInfo fi = new FileInfo(file);
if (fi.LastWriteTime < DateTime.Now.AddDays(iDayDelAge * -1)) // overdue?
{
fi.Delete();
}
}
// Recursively search next subfolder if available
foreach (String subfolder in Directory.GetDirectories(sPath))
{
CleanupFiles(subfolder, iDayDelAge);
}
// Remove empty folder
if (Directory.GetFiles(sPath).Length == 0 && Directory.GetDirectories(sPath).Length == 0)
{
Directory.Delete(sPath);
}
}
}
void清理文件(字符串sPath,int-iDayDelAge)
{
如果(iDayDelAge!=0)//已启用?
{
//检查要删除的旧文件
foreach(Directory.GetFiles(sPath)中的字符串文件)
{
FileInfo fi=新的FileInfo(文件);
如果(fi.LastWriteTime
稍微更改一下代码。
添加一个新的参数根,并在递归调用中将其作为false传递
static void Main(string[] args)
{
CleanupFiles(xxx, xxx, true);
}
void CleanupFiles(String sPath, int iDayDelAge, bool root)
{
if (iDayDelAge != 0) // enabled?
{
// Check for aged files to remove
foreach (String file in Directory.GetFiles(sPath))
{
FileInfo fi = new FileInfo(file);
if (fi.LastWriteTime < DateTime.Now.AddDays(iDayDelAge * -1)) // overdue?
{
fi.Delete();
}
}
// Recursively search next subfolder if available
foreach (String subfolder in Directory.GetDirectories(sPath))
{
CleanupFiles(subfolder, iDayDelAge, false);
}
// Remove empty folder
if (Directory.GetFiles(sPath).Length == 0 && Directory.GetDirectories(sPath).Length == 0 && !root)
{
Directory.Delete(sPath);
}
}
}
static void Main(字符串[]args)
{
清理文件(xxx,xxx,true);
}
无效清除文件(字符串sPath、int iDayDelAge、布尔根)
{
如果(iDayDelAge!=0)//已启用?
{
//检查要删除的旧文件
foreach(Directory.GetFiles(sPath)中的字符串文件)
{
FileInfo fi=新的FileInfo(文件);
如果(fi.LastWriteTime
我不会搞递归删除。并使用DirectoryInfo
类删除目录
void CleanupFiles(String sPath, int iDayDelAge)
{
if (iDayDelAge == 0) // enabled?
{
return;
}
// Check for aged files to remove
foreach (String file in Directory.GetFiles(sPath))
{
FileInfo fi = new FileInfo(file);
if (fi.LastWriteTime < DateTime.Now.AddDays(iDayDelAge * -1)) // overdue?
{
fi.Delete();
}
}
foreach (String subfolder in Directory.GetDirectories(sPath))
{
var dirInfo = new DirectoryInfo(subfolder);
dirInfo.Delete(true);
}
}
void清理文件(字符串sPath,int-iDayDelAge)
{
如果(iDayDelAge==0)//已启用?
{
返回;
}
//检查要删除的旧文件
foreach(Directory.GetFiles(sPath)中的字符串文件)
{
FileInfo fi=新的FileInfo(文件);
如果(fi.LastWriteTime
您也可以依赖Microsoft提供的API,而不是显式递归:
foreach (var file in Directory.GetFiles(sPath))
{
File.Delete(file);
}
foreach (var directory in Directory.GetDirectories(sPath, "*", SearchOption.TopDirectoryOnly))
{
Directory.Delete(directory, true);
}
这应该首先删除根目录(spath)中的所有文件,然后递归删除所有子目录以及内容。此示例应该按照您所描述的那样工作
public static void Main() {
var start = new DirectoryInfo( @"C:\Temp\Test" );
CleanupFiles( start, 5, true );
}
/// <summary>
/// <para>Remove any files last written to <paramref name="daysAgo"/> or before.</para>
/// <para>Then recursively removes any empty sub-folders, but not the starting folder (when <paramref name="isRootFolder"/> is true).</para>
/// <para>Attempts to remove any old read-only files also.</para>
/// </summary>
/// <param name="directory"></param>
/// <param name="daysAgo"></param>
/// <param name="isRootFolder"></param>
/// <param name="removeReadOnlyFiles"></param>
public static void CleanupFiles( [NotNull] DirectoryInfo directory, int daysAgo, Boolean isRootFolder, Boolean removeReadOnlyFiles = true ) {
if ( directory == null ) {
throw new ArgumentNullException( paramName: nameof( directory ) );
}
if ( daysAgo < 1 ) {
return;
}
directory.Refresh();
if ( !directory.Exists ) {
return;
}
var before = DateTime.UtcNow.AddDays( -daysAgo );
// Check for aged files to remove
Parallel.ForEach( directory.EnumerateFiles().AsParallel().Where( file => file.LastWriteTimeUtc <= before ), file => {
if ( file.IsReadOnly ) {
if ( removeReadOnlyFiles ) {
file.IsReadOnly = false;
}
else {
return;
}
}
file.Delete();
} );
foreach ( var subfolder in directory.EnumerateDirectories() ) {
CleanupFiles( subfolder, daysAgo, false, removeReadOnlyFiles );
}
if ( !isRootFolder ) {
if ( !directory.EnumerateDirectories().Any() && !directory.EnumerateFiles().Any() ) {
directory.Delete();
}
}
}
}
publicstaticvoidmain(){
var start=newdirectoryinfo(@“C:\Temp\Test”);
清理文件(开始,5,真);
}
///
///删除上次写入或之前写入的所有文件。
///然后递归删除所有空子文件夹,但不删除起始文件夹(如果为true)。
///还尝试删除任何旧的只读文件。
///
///
///
///
///
公共静态无效清除文件([NotNull]DirectoryInfo目录,int daysAgo,布尔值isRootFolder,布尔值removeReadOnlyFiles=true){
if(目录==null){
抛出新ArgumentNullException(paramName:nameof(目录));
}
if(daysAgo<1){
返回;
}
directory.Refresh();
如果(!directory.Exists){
返回;
}
var before=DateTime.UtcNow.AddDays(-daysAgo);
//检查要删除的旧文件
Parallel.ForEach(directory.EnumerateFiles().AsParallel().Where(file=>file.LastWriteTimeUtc{
如果(file.IsReadOnly){
如果(仅删除文件){
file.IsReadOnly=false;
}
否则{
返回;
}
}
Delete();
} );
foreach(目录.EnumerateDirectory()中的var子文件夹){
清理文件(子文件夹、daysAgo、false、removeReadOnlyFiles);
}
如果(!isRootFolder){
如果(!directory.EnumerateDirectories().Any()&&&!directory.EnumerateFiles().Any()){
directory.Delete();
}
}
}
}
我想看看这个异步版本是如何工作的。给你
public class Program {
public static async Task Main( String[] args ) {
await TestCleaningFolders.Test().ConfigureAwait(false);
}
}
public class TestCleaningFolders {
public static async Task Test() {
var start = new DirectoryInfo( @"T:\Temp\Test" );
var cancel = new CancellationTokenSource();
var olderThan = DateTime.UtcNow.AddDays( -5 );
var onException = new Action<Exception>( exception => Console.WriteLine( exception.ToString() ) ); //could easily be other logging or something..
await CleanupFilesAsync( start, olderThan, deleteEmptyFolders: true, removeReadOnlyFiles: true, onException: onException, token: cancel.Token )
.ConfigureAwait( false );
}
/// <summary>
/// <para>Remove any files last written to on or before <paramref name="olderThan" />.</para>
/// <para>Then recursively removes any empty sub-folders, but not the starting folder (when <paramref name="deleteEmptyFolders" /> is true).</para>
/// <para>Attempts to remove any old read-only files also.</para>
/// </summary>
/// <param name="folder"></param>
/// <param name="olderThan"></param>
/// <param name="deleteEmptyFolders"></param>
/// <param name="removeReadOnlyFiles"></param>
/// <param name="onException"></param>
/// <param name="token"></param>
[NotNull]
public static Task CleanupFilesAsync( [NotNull] DirectoryInfo folder, DateTime olderThan, Boolean deleteEmptyFolders, Boolean removeReadOnlyFiles,
[CanBeNull] Action<Exception> onException, CancellationToken token ) {
if ( folder is null ) {
throw new ArgumentNullException( nameof( folder ) );
}
return Task.Run( async () => {
folder.Refresh();
if ( folder.Exists ) {
if ( ScanAndRemoveOldFiles() ) {
await ScanIntoSubFolders().ConfigureAwait( false );
RemoveFolderIfEmpty();
}
}
}, token );
void Log<T>( T exception ) where T : Exception {
Debug.WriteLine( exception.ToString() );
if ( Debugger.IsAttached ) {
Debugger.Break();
}
onException?.Invoke( exception );
}
Boolean ScanAndRemoveOldFiles() {
try {
foreach ( var file in folder.EnumerateFiles().TakeWhile( info => !token.IsCancellationRequested ) ) {
RemoveFileIfOld( file );
if ( token.IsCancellationRequested ) {
return false; //Added another check because a delete operation itself can take time (where a cancel could be requested before the next findfile).
}
}
}
catch ( UnauthorizedAccessException exception ) {
Log( exception );
return false;
}
catch ( SecurityException exception ) {
Log( exception );
return false;
}
catch ( DirectoryNotFoundException exception ) {
Log( exception );
return false;
}
catch ( IOException exception ) {
Log( exception );
}
return true;
}
void RemoveFileIfOld( FileInfo fileInfo ) {
if ( fileInfo is null ) {
throw new ArgumentNullException( paramName: nameof( fileInfo ) );
}
try {
if ( !fileInfo.Exists || fileInfo.LastWriteTimeUtc > olderThan ) {
return;
}
if ( fileInfo.IsReadOnly ) {
if ( removeReadOnlyFiles ) {
fileInfo.IsReadOnly = false;
}
else {
return;
}
}
fileInfo.Delete();
}
catch ( FileNotFoundException exception ) {
Log( exception );
}
catch ( SecurityException exception ) {
Log( exception );
}
catch ( UnauthorizedAccessException exception ) {
Log( exception );
}
catch ( IOException exception ) {
Log( exception );
}
}
async Task ScanIntoSubFolders() {
try {
foreach ( var subfolder in folder.EnumerateDirectories().TakeWhile( info => !token.IsCancellationRequested ) ) {
await CleanupFilesAsync( subfolder, olderThan, deleteEmptyFolders: true, removeReadOnlyFiles: removeReadOnlyFiles, onException, token: token )
.ConfigureAwait( false );
}
}
catch ( DirectoryNotFoundException exception ) {
Log( exception );
}
catch ( SecurityException exception ) {
Log( exception );
}
catch ( UnauthorizedAccessException exception ) {
Log( exception );
}
catch ( IOException exception ) {
Log( exception );
}
}
void RemoveFolderIfEmpty() {
try {
if ( !deleteEmptyFolders || folder.EnumerateDirectories().Any() || folder.EnumerateFiles().Any() ) {
return;
}
folder.Delete();
}
catch ( FileNotFoundException exception ) {
Log( exception );
}
catch ( DirectoryNotFoundException exception ) {
Log( exception );
}
catch ( SecurityException exception ) {
Log( exception );
}
catch ( UnauthorizedAccessException exception ) {
Log( exception );
}
catch ( IOException exception ) {
Log( exception );
}
}
}
}
公共类程序{
公共静态异步任务主(字符串[]args){
wait TestCleaningFolders.Test().configurewait(false);
}
}
公共类TestCleaningFolders{
公共静态异步任务测试(){
var start=newdirectoryinfo(@“T:\Temp\Test”);
var cancel=新的CancellationTokenSource();
var olderThan=DateTime.UtcNow.AddDays(-5);
var-onException=new Action(exception=>Console.WriteLine(exception.ToString());//很可能是其他日志记录或其他内容。。
等待CleanupFileAsync(开始,olderThan,deleteEmptyFolders:true,removeReadOnlyFiles:true,OneException:OneException,令牌:cancel.token)
.配置等待(错误);
}
///
///删除上次在或之前写入的所有文件。
///然后递归删除所有空子文件夹,但不删除起始文件夹(如果为true)。
///还尝试删除任何旧的只读文件。
///
///
///
///
///
///
///
[不