Страница 2 из 3
Re: Проверка существования файла
Добавлено: 11 июн 2009, 17:23
azrael
Romeo писал(а):azrael, ты говоришь о функции ATLPath::FileExists? Если да, то эта функция не является "стандартной". Для её вызова нужно подключать библиотеку ATL, что не является правильным решением, если при подключении библиотеки будет вызвана всего одна функция из этой библиотеки и, более того, если существует полноценный аналог не использующий никаких других библиотек.
Ну, аналог не "существует", а написан вами, а значит потенциально может содержать ошибки, чего и следует (по моему личному мнению, конечно), по возможности, избегать, используя уже написанные функции в тысячу раз отлаженных библиотеках.
Совсем уж непонятно, что вы имели ввиду под "вызвана всего одна функция". Сколько вам нужно вызвать функций, чтобы считать подключение библиотеки оправданным?

Re: Проверка существования файла
Добавлено: 11 июн 2009, 18:08
Romeo
Если есть функция access из stdlib, которая проверяет существует ли файл и какие у него права, то подключать ATL ради вызова функции, которая делает то же самое (да ещё и с правами работать не умеет), я считаю ненужным.
Даже если бы функции access не существовало, я считаю, что подключение ATL ради функции из двух строк является никому ненужным занятием.
Критерий оправданности подключения библиотеки в моих глазах выглядит следующим образом. Мы должны подключать библиотеку в сугубо специфических случаях, когда написание кода с такой же функциональностью выливается в многие человеко-часы кодинга и тестирования. Ради одной утилитарной функции, аналог которой реализуется в две строки подключать библиотеку глупо.
Re: Проверка существования файла
Добавлено: 11 июн 2009, 18:45
Hawk
azrael писал(а):Ну, аналог не "существует", а написан вами, а значит потенциально может содержать ошибки, чего и следует (по моему личному мнению, конечно), по возможности, избегать, используя уже написанные функции в тысячу раз отлаженных библиотеках.
Совсем уж непонятно, что вы имели ввиду под "вызвана всего одна функция". Сколько вам нужно вызвать функций, чтобы считать подключение библиотеки оправданным?
Ко всему надо подходить с умом. В виндовых проектах windows.h всегда подключен и все необходимые библиотеки для WinAPi функций уже есть. Если вы думаете что GetFileAttributes - настолько сложная функция что боитесь ею пользоваться - вперед подключайте другие библиотеки. Только давайте чуть задумаемся что они делают и что это может за собой повлечь.
ATL:: FileExists
Код: Выделить всё
inline BOOL FileExists( __in const char* pszPath )
{
return ::PathFileExistsA( pszPath );
}
Вроде все элементарно просто. Но PathFileExists - не входит в стандартное API это расширение шела. Оно требует подключения к проекту shlwapi.lib и загружает дополнительную dll shlwapi.dll, которые ещё и могут отличаться на разных версиях винды. Конечно чего нам мелочиться, но ради одной "утилитарной функции" ((С) Romeo) я бы лично этого делать не стал.
access
Поискав её в MSDN можно найти такую строчку -
"This POSIX function is deprecated beginning in Visual C++ 2005. Use the ISO C++ conformant _access or security-enhanced _access_s instead."
Что уже не приятно.
Дальше покопавшись немного можно найти её реализацию -
Код: Выделить всё
errno_t __cdecl _taccess_s (
const _TSCHAR *path,
int amode
)
{
DWORD attr;
_VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE( (path != NULL), EINVAL);
_VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE( ((amode & (~6)) == 0), EINVAL);
attr = GetFileAttributes((LPTSTR)path);
if (attr == 0xffffffff) {
/* error occured -- map error code and return */
_dosmaperr(GetLastError());
return errno;
}
if(attr & FILE_ATTRIBUTE_DIRECTORY)
{
/* All directories have read & write access */
return 0;
}
/* no error; see if returned premission settings OK */
if ( (attr & FILE_ATTRIBUTE_READONLY) && (amode & 2) ) {
/* no write permission on file, return error */
_doserrno = E_access;
errno = EACCES;
return errno;
}
else
/* file exists and has requested permission setting */
return 0;
}
Никакой фантастики тут нет, тот же GetFileAttributes. access мне лично гораздо больше нравится чем atl-ная реализация. Он хоть не требует ничего дополнительного. Но ничего гениального и тут нет. И особого смысла её использовать нет. Разве что для переносимости. Но, как показывает практика, переносимость понятие тоже растяжимое, и проще от этого сильно не будет. А вот то что её могут сделать depricated это пожалуйста.
Библиотеки это конечно полезное дело, но подключать их только из за того что там есть функция на 5 строчек, которую ну очень страшно написать по тому как она будет "написана нами" по мне дак странно. Может в таком случае лучше ничего не писать, там ведь могуть быть потенциальные баги
Re: Проверка существования файла
Добавлено: 15 июн 2009, 15:25
WinMain
Проверить наличие файла по имени можно так же с помощью функции FindFirstFile или FindFirstFileEx. Но суть даже не в этом. Какую бы функцию для этого вы не использовали, если предполагается каждый раз обращаться к файловой системе, то это уже не есть хорошо.
Предлагаю другой способ: сначала нужно составить список уже имеющихся в данном каталоге файлов (с помощью функций FindFirstFile и FindNextFile), а при создании нового файла, имя этого файла добавлять в данный список. Тогда при проверке существования файла с заданным именем нужно будет просто обратиться к списку.
Re: Проверка существования файла
Добавлено: 15 июн 2009, 18:58
Romeo
А если файл был добавлен/удалён сторонней программой после того, как список файлов в директории был закеширован в список?
Можно, конечно, повесить хук на изменения содержимого директории, но, боюсь, этот способ ещё более дорогой с точки зрения перфоменса, чем периодический простой опрос существования файла.
Re: Проверка существования файла
Добавлено: 15 июн 2009, 20:11
WinMain
Я думаю, надо рассматривать ситуацию в контексте самой задачи. Если запись файла происходит в произвольный момент работы приложения, тогда конечно проще воспользоваться любой подходящей функцией для проверки наличия файла. Здесь сам пользователь может удалить какие-то файлы или записать новые.
Но если запись файлов происходит в некой циклической процедуре, то это уже совсем другая ситуация. Сама процедура по времени может занять всего несколько секунд, но за это время успеет записать не одну сотню файлов. Предположим, скачивает картинки из сети или записывает в файлы содержимое базы данных. Всё это происходит обычно в отдельном каталоге самой программы и говорить о вмешательстве каких-то сторонних процессов здесь вряд ли стоит. Тогда кэширование списка файлов окажет реальную пользу.
Re: Проверка существования файла
Добавлено: 15 июн 2009, 23:01
Romeo
В целом согласен. Есть только один нюанс.
Если кешировать список файлов, то только после локинга директории на запись. Даже если работа с файлами в директории будет происходить всего доли секунды, то всё равно есть шанс, что кто-то другой успеет записать в эту папку файл и мы получим assert, который, к примеру, повлечёт за собой намеренный краш системы (часто в assert'ах делают искусственный краш) либо любое другое неадекватное поведение программы. Если есть любой (не важно насколько малый) шанс неправильной работы системы - этот шанс следует устранить.
Re: Проверка существования файла
Добавлено: 15 июн 2009, 23:24
evgenrpo
Проверку файла мне нада было сделать чтоб существующий с таким именем не перезаписывался(тоисть не терялись данные). Авинда говорила что такой файл уже существует и не мог такой создать уже файл.
Использувал CreateFile(). в моей ситуации она нормально баботает.
Всем спасибо за ету тему.
Появилась новая проблема перейдите в тему (Наверное запорол прогу) Пожалуйста!!!
Re: Проверка существования файла
Добавлено: 16 июн 2009, 10:23
BBB
Есть еще в WinAPI замечательная функция (напамять не вспомню названия) как "получить уникальное имя врЕменного файла". Я неоднократно ей пользовался. Минус у нее тот, что имя файла получается вида 'a645f9.tmp'. Т.е. если для задачи непринципиальна такая "тарабарщина", то функция, на мой взгляд весьма удобна.
Re: Проверка существования файла
Добавлено: 16 июн 2009, 10:30
Romeo
Да, есть такая. Называется GetTempFileName. Только это не относится к теме. Вопрос был "как узнать существует ли файл".