С++: что является лучшим методом проверки существования файла на платформе Windows
Возможный дубликат:
Как проверить, существует ли файл с помощью программы Win32 или нет?
Каков наилучший метод проверки существования файла:
Option1:
GetFileAttributes("C:\\MyFile.txt"); // from winbase.h
if(0xffffffff == GetFileAttributes("C:\\MyFile.txt"))
{
//File not found
}
Option2:
std::string fileName("C:\\MyFile.txt" );
ifstream fin( fileName.c_str() );
if( fin.fail() )
{
//File not found
}
Также, если вы считаете, что вариант 1 - лучший метод, можете ли вы сказать мне, как определить 0xffffffff
как константу (я не хочу использовать #define)
Спасибо
Ответы
Ответ 1
Обратите внимание, что GetFileAttributes() может завершиться по другим причинам, кроме отсутствия существования (например, проблемы с разрешениями). Я бы добавил проверку кода ошибки на надежность:
GetFileAttributes("C:\\MyFile.txt"); // from winbase.h
if(INVALID_FILE_ATTRIBUTES == GetFileAttributes("C:\\MyFile.txt") && GetLastError()==ERROR_FILE_NOT_FOUND)
{
//File not found
}
Ответ 2
Здесь есть две вещи:
-
Проверка наличия файла через его атрибуты на несколько порядков быстрее - если файл существует в "медленной" файловой системе - лента, сетевое хранилище, cd и т.д., тогда открытие файла будет включать в себя фактический раунд поездка в расположение файлов. Атрибуты файлов, с другой стороны, запрашиваются и кэшируются драйверами файловой системы при запросе каталога, поэтому атрибуты пробного файла включают стоимость переустановки каталога за один раз - это означает гораздо меньшее количество поездок в оба конца, что может быть значительной экономией, если несколько "медленных" файлы проверяются.
-
Однако атрибуты файлов просто указывают, что файл существовал во время вызова. Файл можно удалить, иначе вы не сможете получить доступ к нему. Если вы все равно попытаетесь открыть файл, было бы лучше обойтись без проверки атрибутов файлов и попробовать и открыть файл.
Ответ 3
Если вы настроите таргетинг только на Windows, опция №1 явно лучше двух. Кроме того, константа, которую вы ищете, уже существует в заголовках Windows - она называется INVALID_FILE_ATTRIBUTES
.
Ответ 4
Как насчет повышения использования?
if (!boost::filesystem::exists("C:\\MyFile.txt"))
{
...
}
http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm
Ответ 5
Единственный надежный способ проверить, существует ли файл, - попытаться открыть его и посмотреть, удастся ли ему выполнить или не удается.
Любой другой метод - это потенциальное состояние гонки. Например, GetFileAttributes
может сказать вам, существовал ли файл при вызове функции, но это не то же самое, что оно существует, когда вы пытаетесь его открыть. Тем временем он мог быть удален (или создан).
Ответ 6
Я бы предпочел первый. Второй проверяет, может ли файл быть открыт, в то время как файл может существовать, если у вас нет прав на его открытие.
Вы можете использовать константу INVALID_FILE_ATTRIBUTES
.
Ответ 7
Я бы предпочел использовать iostream
из-за своей независимости от платформы. Правда, вы можете ориентироваться только на Windows, но никогда не ошибаетесь, чтобы использовать библиотеки, независимые от платформы. Если вы строите большой проект, вы никогда не знаете, что пойдет в следующий этап.
Я не уверен, что приведенный выше код является лучшим (или правильным) способом проверки существования файла. Попробуйте this:
ifstream f;
f.open(str);
if (f.is_open()) {
// read file
}
Ответ 8
Я также хочу подтвердить, что строка не является каталогом:
DWORD attr = GetFileAttributes(file);
if(attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY))
return false; // not a file
return true;
Ответ 9
В тот же день все, что у нас было, было OpenFile (и мы были GRATEFUL)
OFSTRUCT of = {0};
of.cBytes = sizeof(of);
HFILE hf = ::OpenFile("c:\\windows\\write.exe",&of,OF_EXIST);
if(hf > 0)
printf("file exists");
return 0;
Ответ 10
Для этого есть полезная функция утилиты оболочки, PathFileExists.
Ответ 11
#include <iostream>
#include <windows.h>
using namespace std;
bool FileExists(const TCHAR *fileName)
{
DWORD fileAttr;
fileAttr = GetFileAttributes(fileName);
if (0xFFFFFFFF == fileAttr && GetLastError()==ERROR_FILE_NOT_FOUND)
return false;
return true;
}
int main(int argc, char *argv[])
{
if ( FileExists("testtt.txt"))
{
cout << "File exists \n";
}
else
{
cout << "File does not exist \n";
}
return 0;
}