在一个目录中,除了特定的文件扩展名之外,最快的删除文件的方法是什么?

11

我曾经看到过类似的问题:什么是清空目录的最佳方法?

但是我需要知道:

在一个目录中,如何最快地删除所有文件,除了指定后缀名为 .zip 的文件外。

这里似乎有 Linq 的味道... 还是其他方法?

所谓最快的方式,就是指最短的执行时间。


你在用什么编程语言/操作系统进行这个项目? - Eli
我认为 C#/LINQ 标签已经足够了 @Eli - Marko
LINQ不会比任何其他方法更快;它仍然必须以某种方式枚举文件。瓶颈是您的磁盘,而不是负责发送请求的代码。 - Cody Gray
4个回答

12

如果你在使用.NET 4,你可以聪明地利用 .NET 现在可以并行化你的函数。这段代码是最快的方法。它还会随着处理器内核数量的增加而扩展。

DirectoryInfo di = new DirectoryInfo(yourDir);
var files = di.GetFiles();

files.AsParallel().Where(f => f.Extension != ".zip").ForAll((f) => f.Delete());

8

您是否希望用最少的代码行或最快的执行时间来实现?下面是一个使用LINQ和并行for each循环快速删除的示例。

string[] files = System.IO.Directory.GetFiles("c:\\temp", "*.*", IO.SearchOption.TopDirectoryOnly);

List<string> del = (
   from string s in files
   where ! (s.EndsWith(".zip"))
   select s).ToList();

Parallel.ForEach(del, (string s) => { IO.File.Delete(s); });

抱歉没有提到。我指的是最快的执行时间。 - GeorgeBoy
1
Parallel.ForEach。运行磁盘操作(尤其是HDD操作)并行很可能只会拖慢速度。而关于“最快”,您是否在问代码行数最少还是执行时间最快?这是一个非常奇怪的“快速”定义方式(我的意思是代码行数)。代码行数和速度有什么相关性呢? - illegal-immigrant
下班后我会运行基准测试,但我非常确定并行化会拖慢速度。顺便说一下,这很不幸,因为我喜欢这个想法。 - Renaud Gauthier

7

在撰写本答案时,先前的答案均未使用Directory.EnumerateFiles(),该方法允许您在构建文件列表时继续对列表执行操作。 代码:

Parallel.ForEach(Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).AsParallel(), Item =>
        {
            if(!string.Equals(Path.GetExtension(Item), ".zip",StringComparison.OrdinalIgnoreCase))
                File.Delete(Item);
        });

据我所知,在这种情况下使用AsParallel()得到的性能提升并不显著(如果有),然而在我的个人案例中确实有所变化。
我比较了使用1-foreach、2-parallel foreach、3-IEnumerable().AsParallel().ForAll以及4-parallel foreach using IEnumerable().AsParallel()列举的四种方式来删除4689个文件列表中除.zip文件外的所有文件,其中有10个是zip文件的时间。结果如下:
1-1545
2-1015
3-1103
4-839
第五个和最后一个案例是使用Directory.GetFiles()的常规foreach。
5-2266
当然,这些结果并不具有决定性,据我所知,要进行适当的基准测试需要使用RAM磁盘而不是硬盘驱动器。
请注意:随着文件数的增加,枚举文件和获取文件之间的性能差异变得更加明显。

1
时间是以毫秒为单位吗?无论如何,感谢您实际测试并记录性能差异!!! - Marcus Mangelsdorf

2

这是普通的C#代码

foreach(string file in Directory.GetFiles(Server.MapPath("~/yourdirectory")))
{
    if(Path.GetExtension(file) != ".zip")
    {
        File.Delete(file);
    }
}

这里介绍一下LINQ

var files = from f in Directory.GetFiles("")
            where Path.GetExtension(f) != ".zip"
            select f;

foreach(string file in files)
    File.Delete(file);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接