![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Обнаружил, что стандартные ф-ии FileExists и DirectoryEsxists работают довольно медленно, если с файлом/папкой ведется работа, в связи с этим возникает вопрос, есть ли какой-то более быстрый и простой способ проверки существования файла?
|
|
#2
|
||||
|
||||
|
Подозреваю, что не в функциях дело, скорее всего нужный файл во время проверки занят какимнить процессом, ведь в 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;Код:
var Attr: integer; ... Attr := GetFileAttributes(PChar(FileName)); if (Attr <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Attr = 0) then ... // файл есть |
|
#3
|
||||
|
||||
|
Чота, Мэд, в свете предыдущего поста ты сам себя походу обманул
![]() |
|
#4
|
||||
|
||||
|
Я же и написал, что функции подтупливают, если файл занят, т.к. в теле ф-ии происходит попытка открытия файла.
В принципе я нашел решение как вообще не пользовать эти ф-ии, просто стало интересно, возможно ли как-то штатными методами проверить наличие файла так, чтобы небыло подтупливания. З.Ы. У меня код ф-ии выглядит так (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;Последний раз редактировалось M.A.D.M.A.N., 18.10.2016 в 07:59. |