Вы должны установить связь с библиотеками boost_system и boost_filesystem. Как это сделать, зависит от вашей комбинации компилятор / компоновщик; например, в моей системе я должен добавить флаги -lboost_system-mt -lboost_filesystem-mt
.
Некоторые замечания: В Windows обычно требуется, чтобы wstring
(или другой объект с широким символом) увеличивал ваши шансы на работу с путями Unicode. Во-вторых, вы можете сделать свой код намного короче, используя find_if
и recursive_directory_iterator
:
#include <algorithm>
#include <iostream>
#define BOOST_FILESYSTEM_NO_DEPRECATED
#define BOOST_FILESYSTEM_VERSION 3
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;
bool find_file(const path& dir_path, const path& file_name, path& path_found) {
const recursive_directory_iterator end;
const auto it = find_if(recursive_directory_iterator(dir_path), end,
[&file_name](const directory_entry& e) {
return e.path().filename() == file_name;
});
if (it == end) {
return false;
} else {
path_found = it->path();
return true;
}
}
int main() {
const path myPath = L"/usr/local";
const path myFile = L"filesystem.hpp";
path myFound;
find_file(myPath, myFile, myFound);
wcout << myFound << endl;
}
В моем примере используются функции C ++ 11 auto
и lambda
, присутствующие в GCC 4.6. Если в вашем компиляторе их нет, вы можете легко заменить лямбду объектом предиката, а auto
- явным спецификатором типа:
#include <functional>
class file_name_equal: public unary_function<path, bool> {
public:
explicit file_name_equal(const path& fname): file_name(fname) { }
bool operator()(const directory_entry& entry) const {
return entry.path().filename() == file_name;
}
private:
path file_name;
};
bool find_file_cxx03(const path& dir_path, const path& file_name,
path& path_found) {
const recursive_directory_iterator end;
const recursive_directory_iterator it =
find_if(recursive_directory_iterator(dir_path), end,
file_name_equal(file_name));
if (it == end) {
return false;
} else {
path_found = it->path();
return true;
}
}
Другой хороший вариант избавляется от ссылки на возвращаемое значение с помощью Boost.Optional:
...
#include <boost/optional.hpp>
using namespace std;
using namespace boost;
using namespace boost::filesystem;
optional<path> find_file(const path& dir_path, const path& file_name) {
const recursive_directory_iterator end;
const auto it = find_if(recursive_directory_iterator(dir_path), end,
[&file_name](const directory_entry& e) {
return e.path().filename() == file_name;
});
return it == end ? optional<path>() : it->path();
}
int main() {
const path myPath = L"/usr/local";
const path myFile = L"filesystem.hpp";
wcout << find_file(myPath, myFile).get_value_or("not found") << endl;
}