Форум по Delphi программированию



Вернуться   Форум по Delphi программированию > Все о Delphi > Файловая система
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 17.10.2016, 21:01
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,503
Версия Delphi: XE10
Репутация: выкл
По умолчанию Медленная ф-я (Directory/File)Exists

Обнаружил, что стандартные ф-ии FileExists и DirectoryEsxists работают довольно медленно, если с файлом/папкой ведется работа, в связи с этим возникает вопрос, есть ли какой-то более быстрый и простой способ проверки существования файла?
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #2  
Старый 17.10.2016, 22:42
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Подозреваю, что не в функциях дело, скорее всего нужный файл во время проверки занят какимнить процессом, ведь в sysutils`ах они определены как
Код:
procedure EAX2PChar;
asm
       TEST     EAX, EAX
       JNZ      @@exit
       MOV      EAX, offset['']
@@exit
end;

function FileExists(const FileName: string): Boolean;
const size_TWin32FindData = sizeof(TWin32FindData);
asm
       CALL     EAX2PChar
       PUSH     EAX
       CALL     GetFileAttributes
       INC      EAX
       JZ       @@exit
       DEC      EAX
       AND      AL, FILE_ATTRIBUTE_DIRECTORY
       SETZ     AL
@@exit
end;
...
function DirectoryExists(const Name: string): Boolean;
asm
       PUSH     EAX
       CALL     GetFileAttributes
       INC      EAX
       JZ       @@exit
       DEC      EAX
       AND      AL, FILE_ATTRIBUTE_DIRECTORY
       SETNZ    AL
@@exit
end;
в смысле, быстрее некуда, но правда можно еще с атрибутами файла (они ведь какбе отдельно от состояния файла живут) поиграться, без прокладок, сразу через GetFileAttributes
Код:
var
 Attr: integer;
...

 Attr := GetFileAttributes(PChar(FileName));
 if (Attr <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Attr = 0) then ... // файл есть
Ответить с цитированием
  #3  
Старый 18.10.2016, 04:23
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Санкт-Петербург
Сообщения: 2,903
Репутация: выкл
По умолчанию

Чота, Мэд, в свете предыдущего поста ты сам себя походу обманул
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #4  
Старый 18.10.2016, 07:52
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,503
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Я же и написал, что функции подтупливают, если файл занят, т.к. в теле ф-ии происходит попытка открытия файла.
В принципе я нашел решение как вообще не пользовать эти ф-ии, просто стало интересно, возможно ли как-то штатными методами проверить наличие файла так, чтобы небыло подтупливания.

З.Ы. У меня код ф-ии выглядит так (XE 10):
Код:
function FileExists(const FileName: string; FollowLink: Boolean = True): Boolean;
{$IFDEF MSWINDOWS}

  function ExistsLockedOrShared(const Filename: string): Boolean;
  var
    FindData: TWin32FindData;
    LHandle: THandle;
  begin
    { Either the file is locked/share_exclusive or we got an access denied }
    LHandle := FindFirstFile(PChar(Filename), FindData);
    if LHandle <> INVALID_HANDLE_VALUE then
    begin
      Winapi.Windows.FindClose(LHandle);
      Result := FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0;
    end
    else
      Result := False;
  end;

var
  Flags: Cardinal;
  Handle: THandle;
  LastError: Cardinal;
begin
  Flags := GetFileAttributes(PChar(FileName));

  if Flags <> INVALID_FILE_ATTRIBUTES then
  begin
    if faSymLink and Flags <> 0 then
    begin
      if not FollowLink then
        Exit(True)
      else
      begin
        if faDirectory and Flags <> 0 then
          Exit(False)
        else
        begin
          Handle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
            OPEN_EXISTING, 0, 0);
          if Handle <> INVALID_HANDLE_VALUE then
          begin
            CloseHandle(Handle);
            Exit(True);
          end;
          LastError := GetLastError;
          Exit(LastError = ERROR_SHARING_VIOLATION);
        end;
      end;
    end;

    Exit(faDirectory and Flags = 0);
  end;

  LastError := GetLastError;
  Result := (LastError <> ERROR_FILE_NOT_FOUND) and
    (LastError <> ERROR_PATH_NOT_FOUND) and
    (LastError <> ERROR_INVALID_NAME) and ExistsLockedOrShared(Filename);
end;
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 18.10.2016 в 07:59.
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:14.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2021

ВКонтакте   Facebook   Twitter   Ссылка на Telegram