6

Самый быстрый способ проверить существование файла с использованием стандартного C++/C++11, C++14, C++17/C?

1

Тема: Как быстро проверить существование файла в C++11/14/17 или C?

Я ищу самый быстрый способ проверки существования файла в стандартном C++11, 14, 17 или C. У меня есть тысячи файлов, и перед выполнением операций с ними мне нужно проверить, существуют ли все эти файлы. Что я могу написать вместо /* SOMETHING */ в следующей функции?

inline bool exist(const std::string& name)
{
    /* SOMETHING */
}

Буду признателен за любые советы или рекомендации по этой задаче!

5 ответ(ов)

10

Я собрал тестовую программу, которая запускала каждый из этих методов 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.

1

Вы можете использовать следующий код для проверки существования файла. Он работает нормально и не использует каких-либо сложных возможностей C++:

bool is_file_exist(const char *fileName)
{
    std::ifstream infile(fileName);
    return infile.good();
}

Здесь мы создаем объект std::ifstream, передавая ему имя файла. Затем метод good() используется для проверки, может ли файл быть прочитан без ошибок, что в свою очередь позволяет определить, существует ли файл.

0

Для тех, кто предпочитает библиотеку Boost, вы можете использовать следующий код:

boost::filesystem::exists(fileName)

Но, начиная с ISO C++17, вы можете воспользоваться стандартной библиотекой:

std::filesystem::exists(fileName)

Рекомендуется использовать std::filesystem, если ваша среда разработки поддерживает C++17, так как это позволяет вам избавиться от зависимости от Boost и использовать стандартный функционал языка.

0

Этот код позволяет проверить существование файла с учетом кроссплатформенности для Windows и систем, совместимых с POSIX. В коде используется условная компиляция через директиву #ifdef _WIN32, чтобы подключить нужные заголовочные файлы и определить макрос access для разных операционных систем.

Вот объяснение, как это работает:

  1. Если программа компилируется на Windows (_WIN32 определено), подключается заголовочный файл <io.h>, и функция access переназначается на _access_s, которая является безопасной версией функции access.

  2. Если программа компилируется на 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;
}

Таким образом, этот подход позволяет вам иметь один код, который работает на разных операционных системах без использования сторонних библиотек.

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>, чтобы использовать структуру и функции, связанные с файловой системой.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь