Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как быстро удалить файл? [D7, WinXP]


Страницы:   1 2

rolex ©   (2006-02-16 17:13:00) 

Нужно очитстить каталог Temporaru Internet Files. Делаю это так:
1) если в корзину удалять:
function DeleteRecycled(dir:string):Boolean;
var
 fos:TSHFileOpStruct;
begin
 ZeroMemory(@fos,SizeOf(fos));
 with fos do
   begin
     wFunc:=FO_DELETE;
     fFlags:=FOF_SILENT or FOF_NOCONFIRMATION or FOF_ALLOWUNDO;
     pFrom:=PChar(dir+#0);
   end;
 Result:=(0=ShFileOperation(fos));
end;


2) безвозвратно:
function TForm1.DeleteF(dir:string):Boolean;
var
 fos:TSHFileOpStruct;
begin
 ZeroMemory(@fos,SizeOf(fos));
 with fos do
   begin
     wFunc:=FO_DELETE;
     fFlags:=FOF_SILENT or FOF_NOCONFIRMATION;
     pFrom:=PChar(dir+#0);
   end;
 Result:=(0=ShFileOperation(fos));
end;


Думаю вы все знаете что в этой папке несколько тысяч файлов. И удаление происходит ну ОООЧень долго и той и другой процедурой.
Как быть? Ведь если через винду удалять, то всё происходит гораздо быстрей!


begin...end   (2006-02-19 10:04:00) [1]

> defunct ©   (18.02.06 23:11) [33]

rmdir /s /q -- 17 секунд.


defunct   (2006-02-18 23:11:00) [2]

begin...end ©   (18.02.06 22:20) [32]
respect!

Есть существенное замечание: я НЕ отключал вывод в консоль (просто потому что забыл, как это делается), поэтому в неё выводились имена каждого из удалённых файлов. Вероятно, это и есть главная причина более медленной работы del. Было бы неплохо, если бы кто-нибудь протестировал эту команду, отключив консольный вывод. У меня же на это нет ни времени, ни сил.

для чистоты эксперимента, если не затруднит
rmdir /s


begin...end   (2006-02-18 22:20:00) [3]

> Defunct ©   (18.02.06 20:01) [30]

Честно говоря, проверять очевидные вещи сильного желания нет.

Код на основе указанных мной функций может быть примерно таким:

function DelCommand(const Dir: string): Integer;
var
 FD: TWin32FindData;
 H: THandle;
begin
 Result := 0;
 H := FindFirstFile(PChar(Dir + '*.*'), FD);
 if H <> INVALID_HANDLE_VALUE then
   try
     repeat
       if FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
       begin
         if DeleteFile(Dir + FD.cFileName) then
           Inc(Result)
       end
       else
       begin
         if (StrComp(FD.cFileName, '.') <> 0) and (StrComp(FD.cFileName, '..') <> 0) then
           Inc(Result, DelCommand(Dir + FD.cFileName + '\'))
       end
     until not FindNextFile(H, FD)
   finally
     Windows.FindClose(H)
   end
end


Функция возвращает общее количество удалённых файлов. Путь к каталогу нужно указывать с завершающим слэшем.

Трудно выполнить полностью корректное тестирование, т.к. при работе cmd.exe выполняется много дополнительных действий -- например, работа с консолью.

Для тестирования были созданы две копии папки Temporary Internet Files на томе NTFS. Каждая из них имела размер 123 МБ и содержала 12645 файлов и 21 папку. Первая из них была очищена приведённым выше кодом -- DelCommand('E:\T1\')-- причём функция возвратила именно 12645, т.е. были удалены все файлы. После этого компьютер был перезагружен, и вторая папка очищалась командой del E:\T2 /s /q.

Результаты (Windows XP SP2) таковы:

DeleteFile -- 13 секунд
del        -- 23 секунды


Есть существенное замечание: я НЕ отключал вывод в консоль (просто потому что забыл, как это делается), поэтому в неё выводились имена каждого из удалённых файлов. Вероятно, это и есть главная причина более медленной работы del. Было бы неплохо, если бы кто-нибудь протестировал эту команду, отключив консольный вывод. У меня же на это нет ни времени, ни сил.


app   (2006-02-18 20:18:00) [4]

А вас случайно персональная почта не имеется, если нет то для бедных к нас есть чат


Defunct   (2006-02-18 20:01:00) [5]

> Поэтому, вопреки [3], вряд ли следует ожидать какого-либо ускорения работы за счёт использования этой команды

Не настаиваю, но если вам не составит труда, а также интересен этот вопрос, то предлагаю вам написать и исследовать код из комбинации указанных вами функций, который мог бы сравниться по быстродействие с вышеназванными командами OS. Разумеется если у вас есть на это время и желание этим заняться.


begin...end   (2006-02-18 19:35:00) [6]

> Defunct ©   (18.02.06 19:16) [28]
> информация основана на анализе command.com ms-dos v 6.22.

Я не совсем понимаю, зачем сообщать информацию, относящуюся к MS-DOS, в обсуждении, относящемся к Windows XP.

В XP работа команды DEL, вызванной для удаления нескольких файлов, основана на функциях FindFirstFileW/FindNextFileW/FindClose и DeleteFileW. Поэтому, вопреки [3], вряд ли следует ожидать какого-либо ускорения работы за счёт использования этой команды по сравнению с ручным вызовом указанных функций.


Defunct   (2006-02-18 19:16:00) [7]

>> Знаете нечто больше - говорите сразу.
> Зачем?

Хотя бы для того, чтобы собеседнику было интересно с вами общаться.

> Вопрос в [19] вполне конкретен: "Откуда информация?". Никакой двусмысленности.
информация основана на анализе command.com ms-dos v 6.22.


begin...end   (2006-02-18 19:02:00) [8]

> Defunct ©   (18.02.06 18:56) [26]

> не задавайте двусмысленных вопросов.
А я их и не задаю. Вопрос в [19] вполне конкретен: "Откуда информация?". Никакой двусмысленности.

> Знаете нечто больше - говорите сразу.
Зачем?

> что обозначает "Ой." - удивление? сарказм?
Удивление. Это так важно?


Defunct   (2006-02-18 18:56:00) [9]

> Да, конечно. Например, можно ответить правду.

Я вам уже говорил неоднократно - хотите конструктивного диалога, не задавайте двусмысленных вопросов. Знаете нечто больше - говорите сразу.
что обозначает "Ой." - удивление? сарказм?


begin...end   (2006-02-18 18:32:00) [10]

> Defunct ©   (18.02.06 18:21) [24]

Да, конечно. Например, можно ответить правду.


Defunct   (2006-02-18 18:21:00) [11]

> Тогда почему в [20] дан такой ответ на вопрос?

А разве можно ответить как-то по-другому на [19]?


begin...end   (2006-02-18 17:39:00) [12]

> Defunct ©   (18.02.06 17:34) [22]

> нет, спасибо, все хорошо.

Тогда почему в [20] дан такой ответ на вопрос?

> а вы?

Нет.


Defunct   (2006-02-18 17:34:00) [13]

> begin...end ©   (18.02.06 17:20) [21]

нет, спасибо, все хорошо.
а вы?


begin...end   (2006-02-18 17:20:00) [14]

> Defunct ©   (18.02.06 17:10) [20]

Гы. Болеете?


Defunct   (2006-02-18 17:10:00) [15]

begin...end ©   (18.02.06 16:54) [19]

Ой, кто пришел!
из лесу вестимо.


begin...end   (2006-02-18 16:54:00) [16]

> Defunct ©   (18.02.06 04:56) [3]

> Команды ОС Del/DelTree оптимизированы специально для быстрого
> удаления большого числа файлов - помечают сразу все файлы
> каталога как удаленные и после чего корректируют таблицу
> FAT с наименее возможным количеством обращений к диску.

Ой. Откуда информация?


Джо   (2006-02-18 15:35:00) [17]

> [15] rolex   (18.02.06 09:59)
> А как быть с кодом, для удаления в корзину?
> ...
> Может его тоже можно как-то разогнать?

Не думаю, что это возможно, по крайней мере, докумментированными способами.


Джо   (2006-02-18 15:34:00) [18]

> [16] Anatoly Podgoretsky ©   (18.02.06 11:35)
> Джо ©   (18.02.06 06:12) [12]
> Зато есть встроеные Del/Erase

Это я знаю. Кроме того, у rmdir, как я писал, также есть ключ /s.


Anatoly Podgoretsky   (2006-02-18 11:35:00) [19]

Джо ©   (18.02.06 06:12) [12]
Зато есть встроеные Del/Erase

Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.

C:\Documents and Settings\app>del /?
Удаление одного или нескольких файлов.

DEL [/P] [/F] [/S] [/Q] [/A[[:]атрибуты]] имена
ERASE [/P] [/F] [/S] [/Q] [/A[[:]атрибуты]] имена

 /S          Удаление указанных файлов из всех подкаталогов.


rolex   (2006-02-18 09:59:00) [20]

Для безвозвратного удаления заменил:
function TForm1.DeleteF(dir:string):Boolean;
var
fos:TSHFileOpStruct;
begin
ZeroMemory(@fos,SizeOf(fos));
with fos do
  begin
    wFunc:=FO_DELETE;
    fFlags:=FOF_SILENT or FOF_NOCONFIRMATION;
    pFrom:=PChar(dir+#0);
  end;
Result:=(0=ShFileOperation(fos));
end;

на обычный DeleteFile, стало ГОРАЗДО быстрее.

А как быть с кодом, для удаления в корзину?
function DeleteRecycled(dir:string):Boolean;
var
fos:TSHFileOpStruct;
begin
ZeroMemory(@fos,SizeOf(fos));
with fos do
  begin
    wFunc:=FO_DELETE;
    fFlags:=FOF_SILENT or FOF_NOCONFIRMATION or FOF_ALLOWUNDO;
    pFrom:=PChar(dir+#0);
  end;
Result:=(0=ShFileOperation(fos));
end;

Может его тоже можно как-то разогнать?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо