DirectoryExists — Функция Delphi


delphi directoryexists выполняет нечетное поведение для сетевых отображаемых единиц — function

В delphi XE, когда я вызываю функцию SysUtils DirectoryExists со следующим входом

где Y — это сетевой отображаемый блок, он корректно возвращает false, потому что blabla не существует.

Но когда я вызываю со следующим входом

он возвращает true.

Документация плохая, и я не нашел нигде в среде людей с той же проблемой

Возможно, у кого-то здесь уже была эта проблема, или знаете, что происходит?

    4 2
  • 21 окт 2020 2020-10-21 18:43:05
  • dmd_anfini

2 ответа

Ошибка все еще присутствует в XE8 (и, вероятно, в других версиях). Как было указано выше RRUZ, он находится в реализациях SysUtils BOTH DirectoryExists() и TDirectory.Exists().

Проблема заключается в том, что длинный список «проверок» предполагает, что они являются единственными допустимыми причинами, по которым INVALID_FILE_ATTRIBUTES могут быть возвращены в контексте «существования» папки. Но причина, по которой мы называем эти процедуры, почти всегда, поэтому мы можем проверить, действительно ли мы можем использовать папку, о которой мы спрашиваем. Наличие INVALID_FILE_ATTRIBUTES почти всегда означает, что мы не можем. В любом случае, испытания, проводимые в настоящее время, не дают разумных результатов. Этот факт сам по себе делает его полностью избыточным упражнением, так как он позволяет некоторым другим кодам неисправностей проскальзывать через сеть и устанавливать конечный результат в ИСТИННО, когда этого не должно быть. Хотя я могу только представить, что изначально существовал какой-то метод этого безумия, по принципу «о, он существует, но может быть недействительным», он ошибочно полагает, что будущее может принести еще много кодов, созданных многими неизвестные файловые системы и/или аппаратные средства: поэтому в нижней строке указано, что для 99,9% использования, получение INVALID_FILE_ATTRIBUTES должно означать, что папка не пригодна для использования, и поэтому нелогично разрешать возврат TRUE после того, как она уже установлена.

К сожалению, мы не можем знать, существует ли код, который полагается на настоящее поведение, для определения «существующих путей с проблемами» — в этом случае вызов подпрограммы, как она существует в настоящее время, должна предшествовать проверке проверки синтаксиса пути во-первых: иначе он сказал бы, что путь, описанный с плохим синтаксисом, «существует», что является бессмыслицей! Вы не можете повторно выполнить GetLastError, потому что ошибка будет уже очищена.

Таким образом, единственное средство — обернуть любые Sysutils.DirectoryExists и (к сожалению, также) TDirectory.Exists вызовы с кодом, который устраняет проблему вверх. Например:

Либо это, либо вы делаете отдельную предварительную проверку всех «плохих» случаев, о которых вы знаете, и Embarcadero пропустили — то есть сыграйте в ту же проигрышную игру, что и они. Ужасно, но там вы идете.

Вы также можете самостоятельно изменить библиотеку SysUtils, чтобы добавить отсутствующие случаи, которые вам придется переделать с каждой версией Delphi и для каждого нового случая, с которым вы сталкиваетесь. Вероятно, было бы лучше, если бы Эмбаркадеро наконец «укусил пулю» и нашел лучшее решение этой проблемы. Возможно, используя другой флаг по умолчанию, который говорит «отклонить все недопустимые каталоги». Я бы предположил, что это значение по умолчанию равно TRUE.

Клуб программистов

Delphi programming

Подписаться на рассылку:

DirectoryExists

проверяет существование директории

|| function DirectoryExists ( const DirectoryName : string ) : Boolean;

Описание:

Delphi функция DirectoryExists возвращает True если искомая папка существует. То есть проверяет существование папки.

Поиск папки осуществляется в текущей папке.

False возвращается если искомой директории не существует.

Пример кода:

var
dirName : String;

begin
// Create a new directory
dirName := ‘Test Folder’;
CreateDir(dirName);

// Now see if the directory exists
if DirectoryExists(dirName)
then ShowMessage(dirName+’ exists OK’)
else ShowMessage(dirName+’ does not exist’);

// Delete the directory and look again
RemoveDir(dirName);
if DirectoryExists(dirName)
then ShowMessage(dirName+’ still exists!’)
else ShowMessage(dirName+’ no longer exists’);
end;

Результат выполнения:

Test Folder exists OK
Test Folder no longer exists

Функция delphi directoryexists нечетное поведение для подключенных к сети модулей

В Delphi XE, когда я вызываю функцию SysUtils DirectoryExists со следующим вводом

где Y — это подключенный к сети модуль, он корректно возвращает false, потому что blabla не существует.

Но когда я звоню со следующим входом

‘Y: \ блабла \ Y: \ бла’

это возвращает истину.

Документация плохая, и я нигде не нашел в интернете людей с такой же проблемой

может, у кого-то здесь уже была эта проблема, или знаете, что происходит?

Кажется, ошибка в реализации функции DirectoryExists .

Это соответствующий код этой функции

Как вы видите, если GetFileAttributes функции GetFileAttributes неудачей, результат метода GetLastError сравнивается с набором возможных значений. но в вашем случае передача неверного пути вернет ERROR_BAD_PATHNAME (161), поэтому функция возвращает True.

Ошибка все еще есть в XE8 (и, вероятно, в других версиях тоже). Как указывалось выше RRUZ, он лежит в реализациях SysUtils ОБА DirectoryExists () и TDirectory.Exists () .

Проблема заключается в том, что длинный список «проверок» предполагает, что они являются единственными действительными причинами того, что INVALID_FILE_ATTRIBUTES могли быть возвращены в контексте «существования» папки. Но причина, по которой мы называем эти подпрограммы, почти всегда такова, что мы можем проверить, действительно ли мы можем использовать папку, о которой мы просим. Наличие INVALID_FILE_ATTRIBUTES почти всегда означает, что мы не можем. В любом случае, проводимые в настоящее время испытания не дают ощутимых результатов. Уже один этот факт делает его полностью избыточным упражнением, поскольку он позволяет некоторым другим кодам ошибок проскальзывать через сеть и устанавливать конечный результат в ИСТИНА, когда это не должно быть. Хотя я могу только представить, что изначально в этом безумии был какой-то метод, похожий на «о, он существует, но может быть недействительным», он противоречит присущей ему истине, что будущее может принести еще больше кодов, созданных многими, пока неизвестные файловые системы и / или оборудование: итак, в 99.9% случаев получение INVALID_FILE_ATTRIBUTES должно означать, что папка недоступна для использования , и поэтому нелогично разрешать возвращение TRUE после того, как оно уже установлено.

Илон Маск рекомендует:  Как на vc5 0 создать окошко на full screen

К сожалению, мы не можем знать, существует ли код, который полагается на текущее поведение для идентификации «существующих путей с проблемами» — в этом случае вызову подпрограммы в том виде, в каком она существует в настоящее время, должна предшествовать проверка валидации синтаксиса пути: в противном случае было бы сказано, что путь, описанный с плохим синтаксисом, «существует», что является чепухой! Вы не можете повторить GetLastError впоследствии, потому что ошибка уже будет очищена.

Поэтому единственное лекарство — это обернуть любые вызовы Sysutils.DirectoryExists и (к сожалению, также) TDirectory.Exists кодом, который устраняет проблему заранее . Например:

Либо так, либо вы проводите отдельную предварительную проверку всех «плохих» случаев, о которых вы знаете, а Embarcadero пропустили — то есть играете в ту же проигрышную игру, что и они. Ужасно, но вы идете.

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

DirectoryExists — Функция Delphi

Приветствую. На работе стоит древняя D5 в которой нет функии DirectoryExists

Выложите пожалуйста полную функцию из D7 например.

function DirectoryExists(const Directory: string): Boolean;
<$IFDEF LINUX>
var
st: TStatBuf;
begin
if stat(PChar(Directory), st) = 0 then
Result := S_ISDIR(st.st_mode)
else
Result := False;
end;
<$ENDIF>
<$IFDEF MSWINDOWS>
var
Code: Integer;
begin
Code := GetFileAttributes(PChar(Directory));
Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;
<$ENDIF>

И еще пожалуйста ForceDirectories функцию.
Буду очень благодарен

А разве FileExists Для директорий не прокатывает?

function ForceDirectories(Dir: string): Boolean;
var
E: EInOutError;
begin
Result := True;
if Dir = «» then
begin
E := EInOutError.CreateRes(@SCannotCreateDir);
E.ErrorCode := 3;
raise E;
end;
Dir := ExcludeTrailingPathDelimiter(Dir);
<$IFDEF MSWINDOWS>
if (Length(Dir)

> @!!ex © (04.06.08 12:16) [4]


> древняя D5 в которой нет функии DirectoryExists

Вот из древней D5

function DirectoryExists(const Name: string): Boolean;
var
Code: Integer;
begin
Code := GetFileAttributes(PChar(Name));
Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;

> На работе стоит древняя D5

Странно, я думал накинуться.


> Kolan © (04.06.08 12:39) [8]
> Странно, я думал накинуться.

И почему передумал?


> Странно, я думал накинуться.

Может и надо.
Я до сих пор на D5. Меня полностью устраивает. Старшие версии еще и не видел.


> silvestr (04.06.08 12:11)
>
> Приветствую. На работе стоит древняя D5 в которой нет функии
> DirectoryExists

А вот код из Д1:
function DirectoryExists(Name: string): Boolean;
var
SR: TSearchRec;
begin
if Name[Length(Name)] = «\» then Dec(Name[0]);
if (Length(Name) = 2) and (Name[2] = «:») then
Name := Name + «\*.*»;
Result := FindFirst(Name, faDirectory, SR) = 0;
Result := Result and (SR.Attr and faDirectory <> 0);
end;

FileCtrl.pas

> Германн (04.06.2008 16:28:11) [11]

Он нас обманывал.


> silvestr (04.06.08 12:11)


> silvestr (04.06.08 12:15) [3]

c миру по нитке — нищему VCL

делфийская функция directoryexists странное поведение для сетевых блоков отображаются

В Дельфах Х, когда я вызываю функцию SysUtils DirectoryExists со следующим входом

где Y представляет собой сеть отображается блок, он правильно возвращает ложь, потому что блаб оленья кожа существует.

Но когда я звоню со следующим входом

‘Y: \ блабла \ Y: \ бла’

она возвращает истину.

Документация бедна, и я не нашел где-нибудь на интернетах людей с той же проблемой

может быть, кто-то здесь уже была такая проблема, или знать, что происходит?

Похоже , ошибка в реализации DirectoryExists функции.

Это соответствующий код этой функции

Как вы видите , если GetFileAttributes вызов функции неудачен, результат GetLastError методы сравнивается с набором возможных значений. но в вашем случае прохождения недопустимый путь будет возвращать ERROR_BAD_PATHNAME (161) код, поэтому функция возвращает True.

Ошибка все еще существует в X Е8 (и , возможно , в других версиях тоже). Как было отмечено выше, RRUZ лежит в реализации SysUtils от ОБОИХ DirectoryExists () и TDirectory.Exists () .


Проблема заключается в том, что с длинным списком «проверок» , что предполагает , что они являются единственными уважительные причины , которые INVALID_FILE_ATTRIBUTES могут быть возвращены в контексте «существования» папки. Но почему мы называем эти процедуры является почти всегда таким образом , мы можем проверить , можем ли мы на самом деле использоватьпапка мы спрашиваем о. Имея INVALID_FILE_ATTRIBUTES почти всегда означает , что мы не можем. В любом случае, тесты в настоящее время сделано не дают разумные результаты. Уже один этот факт делает его совершенно излишним упражнение, так как это позволяет некоторые другие коды ошибок , чтобы проскользнуть через сеть и установить конечный результат TRUE , когда оно не должно быть. Несмотря на то , что я могу только представить себе , что было первоначально некоторый метод к этому безумию, по линии «ой, она существует , но может быть недействительным», он ссорится присущей истина о том , что будущий может принести гораздо больше кодов , генерируемых многими еще неизвестные файловые системы и / или аппаратное обеспечение: так в нижней строке в том , что на 99,9% использование, получая INVALID_FILE_ATTRIBUTES должен означать папку не годную к употреблению, И поэтому нелогично, чтобы позволить ИСТИНА быть возвращены сразу, что уже установлено.

Илон Маск рекомендует:  Безопасное программирование на PHP

К сожалению , мы не можем знать , есть ли код , который полагается на нынешнее поведение , чтобы определить «существующие пути с вопросами» — в этом случае вызов подпрограммы , как это в настоящее время существует бы предшествовать проверка показала путь-синтаксис первой: в противном случае было бы сказать , что путь описывается с плохим синтаксисом «существует», что это нонсенс! Вы не можете повторить GetLastError после этого, потому что уже будет очищена ошибка.

Таким образом, единственное лечение , чтобы обернуть любые Sysutils.DirectoryExists и ( к сожалению , также) TDirectory.Exists вызовов с кодом , который устраняет проблему до фронта. Например:

Либо так, либо вы делаете отдельную авансовые проверку всех «плохих» случаев вы знаете о и Embarcadero пропустило — то есть играть в ту же игру убыточной, как они это делали. Ужасная, но там вы идете.

Кроме того, можно модифицировать библиотеку SysUtils самостоятельно, чтобы добавить недостающие случаи, которые вы должны повторить с каждым выпуском Delphi и для каждого нового случая вы сталкиваетесь. Вероятно , было бы лучше , если бы Embarcadero , наконец , «кусает пулю» и находит лучшее решение для этой проблемы. Возможно , с помощью другого параметра дефолта флага , который говорит «отклонить все недопустимые каталоги». Я хотел бы далее предположить , что это значение по умолчанию равно TRUE.

Функция Faster DirectoryExists?

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

метод возвращает очень много времени.

Должен быть более быстрый способ определить, что сетевая папка недоступна. Или я могу настроить некоторый параметр таймаута, который использует DirectoryExists внутри себя (я смотрел исходный код, но он просто делегирует GetFileAttributes, который определен в kernel32)?

networking delphi delphi-2009

7 ответов

Нет более быстрого способа:

любая функция, получающая доступ к чему-либо на удаленном ресурсе, будет отключена, если этот ресурс недоступен.

Если причиной ваших таймаутов является автоматическое отключение акций, то эта ссылка может вам помочь: http://support.microsoft.com/default.aspx?sc >

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

6 JRL [2009-09-17 16:48:00]

Как сказал codymanix, используйте потоки. Вышеупомянутая ссылка покажет вам, как вы можете это сделать с делегатами на С#. Не знаете Delphi, но, может быть, вы знаете, как преобразовать код?

Если вы тестируете множество каталогов, вы должны использовать потоки для выполнения всех запросов параллельно, потому что для общих сетевых ресурсов обычно длинные таймауты.

3 skamradt [2009-09-17 18:09:00]

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

Кроме того, на некоторых машинах, если UNC-путь находится на локальном компьютере, а на локальном компьютере нет активной сетевой карты (например, отсоединенный Wi-Fi ноутбук, например, в режиме «Самолет» ), запросы UNC также потерпят неудачу.

Я использую следующий код.

. который позволяет мне иметь тайм-аут версии Directory.Exist. Я называю это чем-то вроде.

Будет ли это нормально для вас?

Чтобы быть безопасным/законным, вам необходимо вызвать callback.EndInvoke(result); » но называя его блокировкой до тех пор, пока асинхронная обработка не завершится, так что это победит объект кода. Возможно, это нужно сделать в конце вашего кода — возможно, выйдет?

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

0 pani [2009-09-17 19:34:00]

Если оба компьютера находятся в одном домене, это ускорит операции с файлами при работе с акциями.

Вопрос по delphi-2009, networking, delphi &#8211 Быстрее DirectoryExists функция?

проверить, доступен ли каталог с компьютера или нет. Но если каталог не существует, а имя пути является сетевым, то есть

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

Должен быть более быстрый способ определить, что сетевая папка недоступна. Или я могу настроить некоторый параметр времени ожидания, который DirectoryExists использует внутренне (я посмотрел на исходный код, но он просто делегирует GetFileAttributes, который определен в kernel32)?

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

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

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

Кроме того, на некоторых компьютерах, если путь UNC находится на локальном компьютере, а на локальном компьютере нет активной сетевой карты (например, отключенный ноутбук Wi-Fi в «Самолет» режим), то запросы UNC также не будут выполнены.

Я использую следующий код .

. который позволяет мне иметь версию Directory.Exist с тайм-аутом. Я называю это чем-то вроде .

Илон Маск рекомендует:  Селекторы атрибутов в CSS

Будет ли это нормально для вас?

Чтобы быть в безопасности / законно, тогда вам нужно позвонитьcallback.EndInvoke (результат);» но его вызов блокируется до тех пор, пока не завершится асинхронность, поэтому это побеждает объект кода. Возможно, это нужно сделать в конце кода — возможно, завершится?

Любая функция, получающая доступ к чему-либо на удаленном общем ресурсе, будет отключена, когда этот общий ресурс недоступен.

Если причиной вашего тайм-аута является автоматическое отключение общих ресурсов, эти ссылки могут помочь вам:

Если приложение может продолжить работу без завершения проверки, вы можете поместить проверку в отдельном потоке, а по завершении проверки вы можете обновить свой статус в пользовательском интерфейсе.

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

Как сказал codymanix, используйте темы. Приведенная выше ссылка покажет вам, как вы можете сделать это с делегатами в C #. Дон»Не знаю Delphi, но, может быть, вы знаете, как конвертировать код?

NetDirectoryExists(Path, Timeout)

Он использует Threading и является идеальной альтернативой для TDirectory.Exists(Path)

Использование:

if NetDirectoryExists(‘\\computer1\Data’, 1000) then .

if NetDirectoryExists(‘C:\Folder’, 500) then .

Если папка существует, функции требуется всего несколько миллисекунд, то же самое с несуществующими папками ( C:\NotExisting ). Если это недоступный сетевой путь ( \\ServerNotReady\C$ ) тогда он будет использовать количество миллисекунд, указанное вторым параметром.

Проверка, существует ли файл или папка

При работе с файлами и директориями часто возникают те или иные ошибки. Чтобы отговорить себя хотя бы от части — нужно обязательно проверять, существует ли файл или каталог.

Проверка, существует ли файл или папка:

В процессе разработки очень часто возникает потребность в том, чтобы проверить существует ли файл или папка. В Delphi предусмотрены специальные функции для проверки:

function FileExists ( const FileName : string) : Boolean; — проверяет существует ли файл. В функцию нужно передать имя файла с полным путем к нему. Например, такое ‘c:/1.html’. На выходе получаем булевское значение (истина/ложь).

function DirectoryExists(const Directory: string): Boolean; — принцип работы напоминает принцип предыдущей функции. Только передавать нужно путь к папке. В ответ получаем все те же истину или ложь.

Пример использования:

FileExist может пригодиться, если Вы в программе пытаетесь создать файл, но Вам нужно убедиться, что файла с таким названием нет. Пример с использованием данной функции тут. DirectoryExists тоже может быть очень полезна. Приведу пример. Вам нужно сохранить файл каком-либо каталоге. Если такого каталога не окажется, то файл не сохранится и произойдет ошибка. Так что перед тем как сохранить файл, если Вы не уверены в существовании директории, лучше проверить.

Если Вам нужен пример того, как использовать DirectoryExists — напишите мне в комментариях к статье. Я обязательно придумаю пример и опишу его отдельной статье. В принципе я готов ответить на любые интересующие вопросы — задавайте.

Работа с директориями (папками) в Дельфи

В этой статье я постараюсь познакомить Вас с некоторыми стандартными функциями для работы с директориями. И еще приведу несколько пользовательских функций и примеры их использования. Также рассмотрен вопрос вызова диалога выбора директории.

Для начала начнем с простой функции для создания новой папки. Общий вид функции такой:

То есть если папка успешно создана функция возвращает true. Сразу же простой пример ее использования:

При нажатии на кнопку программа пытается создать папку с именем TestDir на диске C: и если попытка увенчалась успехом, то выводится соответствующее сообщение. Следует отметить, что если вы не указываете имя диска, на котором хотите создавать папку, то функция будет создавать папку в той же директории, где находится сама программа.

приведут к одному и тому же результату.

Теперь рассмотрим функцию для удаления папок. Ее объявление выглядит так:

Сразу же хочу предупредить, что данная функция способна удалять только пустые папки, и если там что-нибудь будет, то произойдет ошибка! Но выход есть. Здесь нам на помощь придет пользовательская функция с простым названием MyRemoveDir. Вот описание функции:

Копируете это все в Вашу программу, а затем эту функцию можно вызвать например так:

Теперь маленько отстранимся от непосредственной работы с папками и рассмотрим волнующий многих вопрос. Как вызвать диалог выбора папки (как при установке программ)?? ПРОСТО.

Подключаем в uses модуль Filectrl.pas (то есть uses FileCtrl;). Теперь ставим на форму еще кнопочку (чтобы не путаться :) и пишем такой код:

При выборе директории в заголовке формы отобразиться ее название!

Теперь рассмотрим следующую процедуру. К примеру Вам надо создать папку Dir1 по адресу: C:\MyDir\Test\Dir1, но при этом папок MyDir и Test на Вашем компьютере не существует. Функция CreateDir здесь не сработает, поэтому воспользуемся процедурой ForceDirectories. Ее общий вид таков:

Пример ее использования (как всегда я поставил на форму новую кнопку, а там написал)

Ну и напоследок приведу функцию для проверки: существует ли директория или нет. Ее общий вид такой:

Если директория указанная в параметре Name существует — то функция возвратит true.

Надеюсь, что помог Вам описанием данных функций и процедур. Сразу хочется дать совет: почаще заглядывайте в HELP, там много интересной и полезной информации!

delphi directoryexists выполняет нечетное поведение для сетевых отображаемых единиц

В delphi XE, когда я вызываю функцию SysUtils DirectoryExists со следующим вводом

где Y — блок с отображением сети, он корректно возвращает false, потому что blabla не существует.

Но когда я звоню со следующим вводом

‘Y: \ блабла \ Y: \ бла’

он возвращает true.

Документация плохая, и я нигде не нашел в сети людей с той же проблемой

возможно, у кого-то здесь уже была эта проблема, или знаете, что происходит?

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL