Ошибка все еще присутствует в XE8 (и, вероятно, в других версиях). Как указано выше RRUZ, это связано с реализациями SysUtils ОБИХ DirectoryExists() и TDirectory.Exists() .
Проблема заключается в том длинном списке «проверок», который предполагает, что они являются единственными действительными причинами того, что INVALID_FILE_ATTRIBUTES мог быть возвращен в контексте «существования» папки. Но причина, по которой мы вызываем эти подпрограммы, заключается в том, что почти всегда мы можем проверить, можем ли мы действительно использовать папку, о которой спрашиваем. Наличие INVALID_FILE_ATTRIBUTES почти всегда означает, что мы не можем. В любом случае, проводимые в настоящее время тесты не дают ощутимых результатов. Уже один этот факт делает это упражнение совершенно излишним, так как оно позволяет некоторым другим кодам неисправностей проскальзывать через сеть и устанавливать конечный результат в ИСТИНА, когда это не должно быть. Хотя я могу только представить, что изначально у этого безумия был какой-то метод, вроде «о, он существует, но может быть недействителен», он противоречит внутренней истине, что будущее может принести гораздо больше кодов, сгенерированных многими до сих пор. неизвестные файловые системы и/или аппаратное обеспечение: таким образом, в 99,9% случаев получение INVALID_FILE_ATTRIBUTES должно означать, что папка непригодна для использования, и поэтому нелогично разрешать TRUE быть возвращены после того, как это уже было установлено.
К сожалению, мы не можем знать, существует ли код, который опирается на настоящее поведение для определения «существующих путей с проблемами» — и в этом случае вызову подпрограммы в том виде, в каком она существует в настоящее время, должна предшествовать проверка синтаксиса пути: в противном случае он сказал бы, что путь, описанный с плохим синтаксисом, «существует», что является нонсенсом! После этого вы не сможете повторить GetLastError, так как ошибка уже будет устранена.
Таким образом, единственное лекарство — обернуть все вызовы Sysutils.DirectoryExists и (к сожалению, также) TDirectory.Exists кодом что устраняет проблему заранее. Например:
DirectoryUsable(const Directory: string; FollowLink: Boolean = True): Boolean;
begin
Result := GetFileAttributes(PChar(Directory)) <> INVALID_FILE_ATTRIBUTES;
if Result then Result := DirectoryExists( Directory, FollowLink );
end;
Либо так, либо вы проводите отдельную предварительную проверку всех «плохих» случаев, о которых вы знаете и которые пропустили Embarcadero, т. е. играете в ту же проигрышную игру, что и они. Ужасно, но вот.
Вы также можете изменить библиотеку SysUtils самостоятельно, чтобы добавить отсутствующие случаи, которые вам придется переделывать с каждым выпуском Delphi и для каждого нового случая, с которым вы сталкиваетесь. Вероятно, было бы лучше, если бы Embarcadero, наконец, «сжала зубы» и нашла лучшее решение этой проблемы. Возможно, используя другой параметр флага по умолчанию, который говорит «отклонить все недопустимые каталоги». Я бы также предположил, что по умолчанию это значение TRUE.
person
Alex T
schedule
12.06.2017