Каков самый быстрый способ удаления файлов в каталоге? (Кроме определенного расширения файла)

Я видел такие вопросы, как Как лучше всего очистить каталог ?

Но мне нужно знать,

как быстрее всего удалить все файлы, найденные в каталоге, за исключением всех найденных файлов .zip.

Здесь пахнет линком... что ли?

Говоря самый быстрый способ, я имею в виду самое быстрое время выполнения.


person GeorgeBoy    schedule 12.02.2011    source источник
comment
На каком языке/ОС вы это делаете?   -  person Eli    schedule 13.02.2011
comment
Я думаю, что тегов C#/LINQ достаточно @Eli   -  person Marko    schedule 13.02.2011
comment
LINQ не будет быстрее любого другого метода; он все еще должен как-то перечислять файлы. Узким местом является ваш диск, а не код, отвечающий за отправку запроса.   -  person Cody Gray    schedule 13.02.2011


Ответы (4)


Если вы используете .NET 4, вы можете воспользоваться умным способом, которым .NET теперь парализует ваши функции. Этот код является быстрым способом сделать это. Это также зависит от количества ядер процессора.

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

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

Под самым быстрым вы просите наименьшее количество строк кода или самое быстрое время выполнения? Вот пример использования LINQ с параллельным циклом для каждого цикла для их быстрого удаления.

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); });
person Daniel Knoodle    schedule 13.02.2011
comment
Извините, что не упомянул об этом. я имел в виду самое быстрое время выполнения - person GeorgeBoy; 13.02.2011
comment
Параллельно.ForEach. Ну, параллельное выполнение дисковых операций (особенно операций с жесткими дисками), скорее всего, просто замедлит работу. И под самым быстрым вы просите наименьшее количество строк кода или самое быстрое время выполнения? - это действительно странное определение скорости (я имею в виду строки кода). Как строки кода соотносятся со скоростью? - person illegal-immigrant; 20.11.2013
comment
Я проведу тест после работы, но я также уверен, что Parallel замедлит работу. К сожалению, кстати, потому что мне нравится эта идея. - person Renaud Gauthier; 20.07.2015

На момент написания этого ответа ни один из предыдущих ответов не использовал Directory.EnumerateFiles(), который позволяет вам выполнять операции со списком файлов во время его создания. Код:

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

насколько я знаю, прирост производительности от использования AsParallel() не должен быть значительным (если он обнаружен) в этом случае, однако в моем случае это имело значение.

Я сравнил время, необходимое для удаления всех файлов, кроме .zip, в списке из 4689 файлов, 10 из которых были zip-файлами с использованием 1-foreach. 2-параллельный foreach. 3-IEnumerable().AsParallel().ForAll. 4-параллельный foreach с использованием IEnumerable().AsParallel(), как показано выше. Результаты:

1-1545

2-1015

3-1103

4-839

пятый и последний случай был обычным foreach с использованием Directory.GetFiles()

5-2266

конечно, результаты не были окончательными, насколько я знаю, чтобы провести правильный бенчмаркинг, вам нужно использовать оперативную память вместо жесткого диска.

Примечание: разница в производительности между EnumerateFiles и GetFiles становится более очевидной по мере увеличения количества файлов.

person ψευδή ηχώ    schedule 29.08.2013
comment
Тайминги в мс? В любом случае, спасибо за фактическое тестирование и документирование различий в производительности!!! - person Marcus Mangelsdorf; 17.03.2016

Вот старый добрый 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);
person Marko    schedule 12.02.2011