+109
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
procedure RemoveDir(path: string);
var
sr: TSearchRec;
begin
if FindFirst(path + '\*.*', faAnyFile, sr) = 0 then
begin
repeat
if sr.Attr and faDirectory = 0 then
DeleteFile(path + '\' + sr.name);
else
RemoveDir(path + '\' + sr.name);
until
FindNext(sr) <> 0;
end;
FindClose(sr);
RemoveDirectory(PChar(path));
end;
История такова, писал я как-то программу по курсовому. (Это было еще года два-три назад, когда я про юнит тесты и различные технологии проектирования и разработки ничего не знал.) По задумки программа распаковывала некие файлы во временный каталог рядом с приложением и по завершению работы с ними удаляла эту папку вот этим методом. Итак, запустил я эту подпрограмму на выполнение для проверки ее работоспособности и смотрю в файловом менеджере, что папка успешно удалилась и все ок. Но вдруг студия начала жаловаться что нет каких-то файлов, я смотрю в файловый менеджер и вижу что файлы проекта программы исчезают буквально на глазах! Естественно я резко убиваю программу и далее начинаю восстанавливать исходники. Благо, что делал бэкапы и эта подпрограмма проработала все ничего, а ведь последствия могли быть еще больше. А мораль такая, нужно быть предельно внимательным, когда работаешь с удалением какой-либо информации.
P.S. Нужно добавить проверку между 10 и 11 строкой:
if (sr.Name <> '..') and (sr.Name <> '.') then
Запостил:
vanished,
18 Декабря 2010
Или нет, не сообразил. Или сообразил только для "..", а для "." забыл. Не помню. Кажется, у меня рекурсия (на ".") вылезла за стек и всё благополучно повисло, и всё.
К тому же в стек помещается только указатель на строку, а сама строка - в динамической памяти через GetMem
Плохая формулировка. Просто "не знал" лучше.
я что-то пропустил оО
VFAT.VXD предоставлял API через INT 21 под VDM (смотрите Ralf Brown's Interrupt List, например). Этот же API предоставляет NTVDM, начиная с Windows XP (в более старых NT надо было ставить сторонний драйвер ntlfn).
Этот же API эмулирует драйвер doslfn (он к тому же умеет читать длинные имена Joliet на сиди-дисках), а также какой-то драйвер из ДР-ДОСа, а ROM-DOS имеет встроенную поддержку длинных имён.
Наконец, драйвер vfat в Линуксе откуда длинные имена берёт?
Обычный заголовок файла — 32 байта — содержит имя (8+3 символа), атрибуты, дату и время создания, размер, указатель на первый кластер и ещё кое-что.
Длинное имя разбивается на слоты, каждый слот содержит 13 уникодных символов (26 байт), символы запихиваются во все поля подряд (они не нужны), в атрибуте стоит 0xf - системный+скрытый+ридонли+метка, а сами слоты помещаются непосредственно перед коротким именем файла. Если мы не будем проверять атрибуты, то FindNext под голым ДОСом (без VFAT) будет находить слоты длинных имён как обычные файлы, размер и указатель на кластер этих слотов, естественно, будут содержать кашу.
IncludeTrailingPathDelimiter() 1 раз в начало дописать. Тем более, что path не const.