Delphi World - RTL.FileExists. Неверный результат при дате файла меньше 1980 г.
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
RTL.FileExists. Неверный результат при дате файла меньше 1980 г.

Автор: Batorov_VA

Функция FileExists в модуле Sysutils.pas дает неверный результат в случае, если дата файла некорректна. В нашем случае создавался файл с датой 1601 г, который не определялся этой функцией.

Эффект проявляется в Delphi 5,6,7.

ТИПОВЫЕ РЕШЕНИЯ

Не давать возможности создаваться таким файлам.

КОММЕНТАРИЙ:

Функция FileExists обосновывает свое решение на результате вызова функции FileAge (см. Sysutils.pas). Последняя возвращает -1 в случае, если попытка определить дату была неуспешна (основной причиной считается невозможность найти файл). Поиск в Sysutils по слову "FileAge" обнаруживает следующий комментарий:

{ FileDateToDateTime converts a DOS date-and-time value to a TDateTime value. The FileAge, FileGetDate, and FileSetDate routines operate on DOS date-and-time values, and the Time field of a TSearchRec used by the FindFirst and FindNext functions contains a DOS date-and-time value. }

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

The MS-DOS date format can represent only dates between 1/1/1980 and 12/31/2107; this conversion fails if the input file time is outside this range.

Последняя функция используется в FileAge для конвертирования даты/времени модификации файла в выходной формат (DOS). Естественно, именно в этом месте происходит ошибка, если дата найденного файла не вписывается в диапазон.

Понять разработчиков runtime библиотеки можно - это было сделано для обратной совместимости с Delphi 1. То есть, программа, использующая старые функции Sysutils, может быть откомпилирована в любой версии Delphi и будет одинаково работать. Кроме того, при штатном использовании даты файла она никогда не может быть меньше даты рождения компьютера, на котором он был создан/изменен. А формат DOS filetime удобен тем, что помещается целиком в 32-битный integer.

Для тех, кто использует дату файла не по назначению, в результате чего она может принимать значение 1601 г, можно посоветовать написать свою функцию FileExists, используя функции API. Для примера можно изучить ту же FileAge.

Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования