Я хотел бы найти самый быстрый способ проверить, существует ли файл в стандарте C ++ 11, C ++ или C. У меня есть тысячи файлов, и прежде чем что-то делать с ними, мне нужно проверить, все ли они существуют. Что я могу написать вместо /* SOMETHING */
следующей функции?
inline bool exist(const std::string& name)
{
/* SOMETHING */
}
boost::filesystem
кажется использоватьstat()
. (Исходя из документации.) Я не думаю, что вы можете делать намного быстрее для вызовов FS. Способ сделать то, что вы делаете быстро, это «избегать просмотра тысяч файлов».git push
вероятно, не стоит беспокоиться, чтобы убедиться, что вы не касаетесь рабочего дерева после начальной грязной проверки.Ответы:
Ну, я собрал тестовую программу, которая запускала каждый из этих методов 100 000 раз, половина для файлов, которые существовали, и половина для файлов, которые не были.
Результаты общего времени для выполнения 100 000 вызовов в среднем за 5 запусков,
Эта
stat()
функция обеспечивала наилучшую производительность в моей системе (Linux, скомпилированный сg++
), при этом стандартныйfopen
вызов - это лучший выбор, если вы по какой-то причине отказываетесь от использования функций POSIX.источник
stat()
кажется, чтобы проверить на существование.f.close()
как f выходит из области видимости в конце функции. Такreturn f.good()
может заменитьif
блок?Примечание: в C ++ 14 и как только файловая система TS будет закончена и принята, решение будет использовать:
и начиная с C ++ 17, только:
источник
std::tr2::sys::exists("helloworld.txt");
std::exists
, это было бы довольно странно (подумайте: существует в контейнере STL, как набор).#include <experimental/filesystem> bool file_exists(std::string fn) { std::experimental::filesystem::exists("helloworld.txt"); }
#include <experimental/filesystem>
Я использую этот кусок кода, пока он работает нормально со мной. Это не использует много необычных функций C ++:
источник
ifstream
деструктор будет вызван при выходеis_file_exist
и закроет поток.return std::ifstream(fileName);
Это зависит от того, где находятся файлы. Например, если все они должны находиться в одном и том же каталоге, вы можете прочитать все записи каталога в хеш-таблицу и затем проверить все имена по хеш-таблице. В некоторых системах это может быть быстрее, чем проверка каждого файла в отдельности. Самый быстрый способ проверить каждый файл в отдельности зависит от вашей системы ... если вы пишете ANSI C, самый быстрый способ
fopen
что это единственный способ (файл может существовать, но не может быть открыт, но вы, вероятно, действительно хотите открыть его, если вы нужно "что-то сделать на этом"). C ++, POSIX, Windows все предлагают дополнительные опции.Пока я занимаюсь этим, позвольте мне указать на некоторые проблемы с вашим вопросом. Вы говорите, что хотите самый быстрый способ, и что у вас есть тысячи файлов, но затем вы запрашиваете код для функции для проверки одного файла (и эта функция действительна только в C ++, но не в C). Это противоречит вашим требованиям, делая предположение о решении ... в случае проблемы XY . Вы также говорите «в стандарте c ++ 11 (или) c ++ (или) c» ... все они разные, и это также не согласуется с вашим требованием к скорости ... самое быстрое решение будет включать адаптацию кода к целевая система. Несоответствие в вопросе подчеркивается тем фактом, что вы приняли ответ, который дает решения, которые зависят от системы и не являются стандартными C или C ++.
источник
Для тех, кто любит повышение:
источник
Без использования других библиотек мне нравится использовать следующий фрагмент кода:
Это работает кроссплатформенно для Windows и POSIX-совместимых систем.
источник
unistd.h
также включать . Может быть, первым#ifdef
должен быть конкретный windows?То же, что предложено PherricOxide, но в C
источник
источник
close()
что нет необходимости.Еще 3 варианта под окнами:
1
2
3
источник
GetFileAttributes
Версия в основном канонический способ сделать это в Windows.Вы также можете сделать
bool b = std::ifstream('filename').good();
. Без инструкций ветвления (например, if) он должен работать быстрее, поскольку его нужно вызывать тысячи раз.источник
Если вам необходимо различать файл и каталог, рассмотрите следующее, в котором используется stat, самый быстрый стандартный инструмент, продемонстрированный PherricOxide:
источник
Мне нужна быстрая функция, которая может проверить, существует файл или нет, и ответ PherricOxide - почти то, что мне нужно, за исключением того, что он не сравнивает производительность boost :: filesystem :: существующие и открытых функций. Из результатов теста мы легко видим, что:
Использование функции stat - это самый быстрый способ проверить, существует ли файл. Обратите внимание, что мои результаты согласуются с результатами ответа PherricOxide.
Производительность функции boost :: filesystem :: exist очень близка к производительности функции stat и также переносима. Я бы порекомендовал это решение, если библиотеки расширения доступны из вашего кода.
Результаты тестов, полученные с ядром Linux 4.17.0 и gcc-7.3:
Ниже приведен мой контрольный код:
источник
Вы можете использовать
std::ifstream
, как funcionis_open
,fail
например, как приведенный ниже код (cout «open» означает, что файл существует или нет):цитируется из этого ответа
источник
где
R
ваша последовательность вещей, похожих на пути, иexists()
от будущего стандартного или текущего повышения. Если вы катите свои собственные, будьте проще,Разветвленное решение не совсем ужасно и не сожрет файловые дескрипторы,
источник
PathFileExists
ограниченоMAX_PATH
(260) символами;GetFileAttributes
не имеет этого ограничения.GetFileAttributes
также ограничен MAX_PATH. Документы описывают обходной путь, если вы используете абсолютные пути, юникод и добавляете специальную строку префикса к имени пути. Я думаю, что мы все равно не согласны с ответами, специфичными для Windows.GetFileAttributesW
не имеет ограничений.В C ++ 17:
источник
Использование MFC возможно с помощью следующих
Где
FileName
строка, представляющая файл, который вы проверяете на наличиеисточник
есть только один более быстрый способ проверить, существует ли файл, и если у вас есть разрешение на его чтение, использование языка C позволяет быстрее и может использоваться в любой версии на C ++
Решение : в C есть библиотека errno.h, которая имеет внешнюю (глобальную) целочисленную переменную с именем errno, которая содержит число, которое можно использовать для распознавания типа ошибки
источник
Хотя есть несколько способов сделать это, наиболее эффективным решением вашей проблемы, вероятно, будет использование одного из предопределенных методов fstream, таких как good () . С помощью этого метода вы можете проверить, существует ли указанный вами файл или нет.
Я надеюсь, что вы найдете это полезным.
источник