Самый быстрый способ проверить существование файла с использованием стандартного C++/C++11, C++14, C++17/C?
Тема: Как быстро проверить существование файла в C++11/14/17 или C?
Я ищу самый быстрый способ проверки существования файла в стандартном C++11, 14, 17 или C. У меня есть тысячи файлов, и перед выполнением операций с ними мне нужно проверить, существуют ли все эти файлы. Что я могу написать вместо /* SOMETHING */
в следующей функции?
inline bool exist(const std::string& name)
{
/* SOMETHING */
}
Буду признателен за любые советы или рекомендации по этой задаче!
5 ответ(ов)
Я собрал тестовую программу, которая запускала каждый из этих методов 100,000 раз: половина на файлах, которые существовали, и половина на тех, которые не существовали.
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <fstream>
inline bool exists_test0 (const std::string& name) {
std::ifstream f(name.c_str());
return f.good();
}
inline bool exists_test1 (const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
inline bool exists_test2 (const std::string& name) {
return (access(name.c_str(), F_OK) != -1);
}
inline bool exists_test3 (const std::string& name) {
struct stat buffer;
return (stat(name.c_str(), &buffer) == 0);
}
Результаты общего времени выполнения 100,000 вызовов, усреднённые за 5 запусков:
Метод | Время |
---|---|
exists_test0 (ifstream) |
0.485s |
exists_test1 (FILE fopen) |
0.302s |
exists_test2 (posix access()) |
0.202s |
exists_test3 (posix stat()) |
0.134s |
Функция stat()
показала наилучшие результаты на моей системе (Linux, скомпилировано с помощью g++
), в то время как стандартный вызов fopen
будет вашим лучшим вариантом, если по какой-то причине вы отказываетесь использовать функции POSIX.
Вы можете использовать следующий код для проверки существования файла. Он работает нормально и не использует каких-либо сложных возможностей C++:
bool is_file_exist(const char *fileName)
{
std::ifstream infile(fileName);
return infile.good();
}
Здесь мы создаем объект std::ifstream
, передавая ему имя файла. Затем метод good()
используется для проверки, может ли файл быть прочитан без ошибок, что в свою очередь позволяет определить, существует ли файл.
Для тех, кто предпочитает библиотеку Boost, вы можете использовать следующий код:
boost::filesystem::exists(fileName)
Но, начиная с ISO C++17, вы можете воспользоваться стандартной библиотекой:
std::filesystem::exists(fileName)
Рекомендуется использовать std::filesystem
, если ваша среда разработки поддерживает C++17, так как это позволяет вам избавиться от зависимости от Boost и использовать стандартный функционал языка.
Этот код позволяет проверить существование файла с учетом кроссплатформенности для Windows и систем, совместимых с POSIX. В коде используется условная компиляция через директиву #ifdef _WIN32
, чтобы подключить нужные заголовочные файлы и определить макрос access
для разных операционных систем.
Вот объяснение, как это работает:
Если программа компилируется на Windows (
_WIN32
определено), подключается заголовочный файл<io.h>
, и функцияaccess
переназначается на_access_s
, которая является безопасной версией функцииaccess
.Если программа компилируется на Unix-подобной системе (например, Linux или macOS), подключается заголовочный файл
<unistd.h>
, который содержит определение для стандартной функцииaccess
.
Функция FileExists
принимает строку с именем файла и возвращает true
, если файл существует, и false
в противном случае. Внутри функции вызывается access
с параметром 0
, что проверяет наличие файла.
Вот пример использования этой функции:
#include <iostream>
#include <string>
#ifdef _WIN32
#include <io.h>
#define access _access_s
#else
#include <unistd.h>
#endif
bool FileExists(const std::string &Filename) {
return access(Filename.c_str(), 0) == 0;
}
int main() {
std::string filename = "test.txt";
if (FileExists(filename)) {
std::cout << "Файл существует." << std::endl;
} else {
std::cout << "Файл не найден." << std::endl;
}
return 0;
}
Таким образом, этот подход позволяет вам иметь один код, который работает на разных операционных системах без использования сторонних библиотек.
Если вам нужно проверить, существует ли файл в C, вы можете использовать следующий код, который аналогичен предложению от PherricOxide:
#include <sys/stat.h>
int exist(const char *name)
{
struct stat buffer;
return (stat(name, &buffer) == 0);
}
Этот код использует функцию stat
для проверки существования файла. Если файл существует и доступен, stat
вернет 0, и функция exist
вернет true (1). В противном случае будет возвращено false (0). Не забудьте подключить заголовочный файл <sys/stat.h>
, чтобы использовать структуру и функции, связанные с файловой системой.
Как изменить цвет вывода echo в Linux
Разница между const int*, const int * const и int * const?
Как использовать extern для обмена переменными между исходными файлами?
Почему переменные нельзя объявлять в операторе switch?
Что такое ошибка сегментации?