Господа,
я столкнулся с этой проблемой — надо удалить из директории некотрые файлы.
Директория плоская, фалов много, конечно, больше одного миллиона, но хотелось красивый заголовок.
Я написал простую утилиту типа
DirectoryInfo info = new DirectoryInfo(PathForDel);
FileInfo[] files = info.GetFiles();
foreach (FileInfo file in files)
{
if (<УСЛОВИЕ УДАЛЕНИЯ>)
file.Delete();
}
и последние сутки она пытается выполнить строчку
FileInfo[] files = info.GetFiles();
Я так понимаю, ускорения работы можно ждать только от прямой работы с MFT?
Нет ли какой библиотеки для .NET, которая позволяет это делать?
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Господа, SLH>я столкнулся с этой проблемой — надо удалить из директории некотрые файлы. SLH>Директория плоская, фалов много, конечно, больше одного миллиона, но хотелось красивый заголовок. SLH>Я написал простую утилиту типа
SLH>
SLH>DirectoryInfo info = new DirectoryInfo(PathForDel);
SLH> FileInfo[] files = info.GetFiles();
SLH> foreach (FileInfo file in files)
SLH> {
SLH> if (<УСЛОВИЕ УДАЛЕНИЯ>)
SLH> file.Delete();
SLH> }
SLH>
SLH>и последние сутки она пытается выполнить строчку SLH>FileInfo[] files = info.GetFiles();
DirectoryInfo и FileInfo имеют довольно значительный оверхед на проверку прав и зачитывание данных о файлах.
Для вашей задачи это, скорее всего, не нужно.
Попробуйте переписать на Directory.GetFiles().
Если не поможет — сделайте dir /b > файл.txt, а потом читайте построчно этот файл вместо.GetFiles().
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Расскажите, кто знает, как продходить к этой задаче?
P/invoke и вызывай findfirstfile/findnextfile или как они там.
Проверяй условия и создавай массив имен, которые удалить.
Потом следующим проходом удаляй.
Мне помнится, на старой винде, типа 2000, лучше было не смешивать проходы сканирования и удаления, а делать два раздельных прохода.
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Господа, SLH>я столкнулся с этой проблемой — надо удалить из директории некотрые файлы.
Помимо +1 к "Directory.EnumerateFiles", в порядке бреда выскажу мысль: возможно, если файлов на удаление очень много, имеет смысл скопировать в отдельную директорию нужные файлы, старую директорию грохнуть и переименовать созданную директорию в старую.
Здравствуйте, господа.
Спасибо всем, кто мне помогал.
Есть одно уточнение:
решил я прикрутить к удалению файлов красивый прогресс — бар.
И для этого понадобилось знать, сколько файлов в директории изначально.
А все способы как это выяснить базируются на... барабанная дробь... Directory.GetFiles()!
То есть, люди не сомневаясь особо, делают Directory.GetFiles().Count.
И даже если переписать это как
long fileCount =0;
foreach (var file in Directory.EnumerateFiles(path, searchPattern, searchOption))
fileCount++;
то все равно — у меня получается двойной оверхед только на то, чтобы сначала посчитать, сколько файлов, а потом уже удалять их.
Как то это тупо. я уверен, что в MFT хранит инфу о кол-ве файлов в директориях,
то есть по крайней мере эту задачу можно решить без получения списка файлов.
Если Вы знаете, как — посоветуйте.
Спасибо!
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Есть одно уточнение: SLH>решил я прикрутить к удалению файлов красивый прогресс — бар. SLH>И для этого понадобилось знать, сколько файлов в директории изначально.
На правах полуоффтопика: в FAR manager если включить эстимейтилку прогресса копирования, оно по-честному делает 2 прохода — один чтобы понять сколько весят все файлы, второй — чтобы копировать.
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Как то это тупо. я уверен, что в MFT хранит инфу о кол-ве файлов в директориях, SLH>то есть по крайней мере эту задачу можно решить без получения списка файлов.
Не будет работать для не-ntfs томов.
Здравствуйте, Sinix, Вы писали:
SLH>>Как то это тупо. я уверен, что в MFT хранит инфу о кол-ве файлов в директориях, SLH>>то есть по крайней мере эту задачу можно решить без получения списка файлов. S>Не будет работать для не-ntfs томов.
Во-первых, я не уверен, что эта информация в виде отдельного значения есть и в NTFS. Точно есть ?
Во-вторых, если даже и узнать, сколько там файлов — это не даст нужного значения для прогресс-бара, о котором говорит ТС. Время удаления файла зависит от его размера и не только.
Здравствуйте, SteeLHeaD, Вы писали:
SLH>решил я прикрутить к удалению файлов красивый прогресс — бар. SLH>И для этого понадобилось знать, сколько файлов в директории изначально.
Видится несколько вариантов:
1. Откуда там эти файлы вообще взялись? Нельзя саму создавалку заставить подсчитывать сколько она их насоздавала и у неё узнавать при удалении?
2. Если первый пункт не вариант — нельзя написать мониторилку файловой системы, которая будет следить за появлением новых файлов и подсчитывать?
3. Если файлы появляются с примерно фиксированной частотой, можно прикинуть, что с момента последней чистки прошло 3 дня, а при частоте 1 файл в час у вас там примерно 72 файла. Соответственно смотрим сколько чистка заняла в прошлый раз, нормируем и пересчитываем на новое количество.
4. Можно вообще показывать какой-нибудь спиннинг вил вместо честного прогресс бара
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Во-первых, я не уверен, что эта информация в виде отдельного значения есть и в NTFS. Точно есть ?
Если ничего не забыл то нет, в атрибутах директории или сам индекс, или ссылка на него, если не влезает. Индекс — обычный btree вроде. Но могу и наврать, давно изучал.
PD>Во-вторых, если даже и узнать, сколько там файлов — это не даст нужного значения для прогресс-бара, о котором говорит ТС. Время удаления файла зависит от его размера и не только.
Не, понятно что зависимость нелинейная будет. Только причина другая. В ntfs емнип удаление сводится к чистке file record в mft. Так что тормоза если и будут, то от фрагментации mft и параллельной загрузке диска. Для ssd, понятно, последнее некритично.
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Как то это тупо. я уверен, что в MFT хранит инфу о кол-ве файлов в директориях, SLH>то есть по крайней мере эту задачу можно решить без получения списка файлов. SLH>Если Вы знаете, как — посоветуйте. SLH>Спасибо!