在递归调用c#后,使计数器返回正确的数字



我有一个名为clearFiles的方法,如果有子目录,可以递归调用它。我创建了一个计数器,用于计算已删除的文件数。当函数被调用一次或递归调用时,计数器会保持正确的数字,但函数末尾的toast只在未递归调用时返回正确的数字。是否可以显示toast,然后重置清除的文件数?因为它只是在递归调用时返回一个0。玩了一段时间后,似乎在filesCleared变量设置为0后调用了toast,这不是我想要的。

filesCleared变量:

int filesCleared = 0;

clearFiles:

public async Task ClearFiles()
{
var pathName = FileFilter.PathName;
FileInfo[] files = SortFiles(pathName);
try
{
if(FileFilter.Filter == "all")
{
foreach(var file in files)
{
if(file.Extension == FileFilter.Extension || FileFilter.Extension == "all")
{
File.Delete(file.ToString());
filesCleared++;
}
}
}
if(FileFilter.Filter == "date")
{            
foreach (var file in files) //regular files
{
if(file.CreationTime < FileFilter.DeleteDate) //based on time
{
if(file.Extension == FileFilter.Extension || FileFilter.Extension == "all") //based on extension
{
File.Delete(file.ToString());
filesCleared++;
}  
}
}
}
if(FileFilter.Filter == "number")
{
var i = 0;
for(var j = files.Length-1; j >= 0 ; j--)
{
if(files[j].Extension == FileFilter.Extension || FileFilter.Extension == "all")
{
if(i++ >= FileFilter.FilesToKeep)
{
File.Delete(files[j].ToString()); 
filesCleared++;
}
}                        
}
}
if (FileFilter.SubFolders == true) //subfiles (will be called recursively w/ each filter)
{
foreach(var subDir in new DirectoryInfo(pathName).GetDirectories())
{
//subDir.Delete(true);
FileFilter.PathName = subDir.ToString();
ClearFiles();
//await ClearFiles(subDir.ToString()); 
}  
FileFilter.PathName = pathName; //resets the pathName so it will go back to what it was before the recursion 
}          
}
catch (IOException ioExp)    
{    
Console.WriteLine(ioExp.Message);    
Toast = Toast.Bad();
logger.LogError(ioExp, "Error Deleting");
}               
Toast = Toast.Good(filesCleared + " Files Deleted");
filesCleared = 0; 
}

如果你想只做一次,但又想递归调用一个方法,你必须把它一分为二。在尝试简化您的代码后,我得到了一个ClearFiles方法,如下所示:

public void ClearFiles()
{
var filesCleared = 0;
try
{
filesCleared = DeleteFilesRecursively(FileFilter.PathName, FileFilter);
}
catch (IOException ioExp)    
{    
Console.WriteLine(ioExp.Message);    
Toast = Toast.Bad();
logger.LogError(ioExp, "Error Deleting");
}               
Toast = Toast.Good(filesCleared + " Files Deleted");
}

现在,在遍历了所有子文件夹之后,Toast.Good只被调用一次。

请注意,filesCleared是一个局部变量,因为我认为使其全局化没有任何意义。这样你也不需要重置它。

DeleteFilesRecursively的实现可以是这样的,如果你想的话,可以简化更多:

private const string All = "all";
private const string FilterByDate = "date";
private const string FilterByNumber = "number";
int DeleteFilesRecursively(string dirPath, SomeFileFilterType fileFilter)
{
FileInfo[] files = SortFiles(dirPath);
var deleted = 0;
var toBeDeleted = files.Where(f => MatchesByExtension(f, fileFilter.Extension));
if (fileFilter.Filter == FilterByDate)
{            
toBeDeleted = toBeDeleted.Where(f => MatchesByDate(f, fileFilter.DeleteDate));
}
else if (FileFilter.Filter == FilterByNumber)
{
// If your SortFiles method sorted in the other
// direction this call to Reverse would not be needed.
toBeDeleted = toBeDeleted.Reverse().Take(fileFilter.FilesToKeep);
}

foreach (var file in toBeDeleted)
{
File.Delete(file.ToString()); 
deleted++;
}
if (fileFilter.SubFolders)
{
foreach(var subDir in new DirectoryInfo(dirPath).GetDirectories())
{
deleted += DeleteFilesRecursively(subDir.FullName, fileFilter);
}
}

return deleted;
}
bool MatchesByExtension(FileInfo file, string extension)
=> file.Extension == extension || extension == All;
bool MatchesByDate(FileInfo file, DateTime deleteDate)
=> file.CreationTime < deleteDate;

请注意,我还删除了您的魔术字符串,用枚举类型替换它们可能会更好。

我还没有测试过这一点,但我相信它应该会给你提供与当前代码相同的行为(至少是关于过滤和删除的部分(。

最新更新