在目录和子目录中搜索文件,使用Boost库C ++ [英] Search files in directory and subdirectory using boost library c++
问题描述
我要创建一个使用C ++也是我不想让麻烦UNI code文件,如阿拉伯命名文件Boost库搜索目录和子目录文件的应用程序。
所以,我该怎么办呢?
更新:
的#include<&iostream的GT;
#包括LT&;升压/文件系统/ operations.hpp>
#包括LT&;升压/文件系统/ fstream.hpp>
#定义BOOST_FILESYSTEM_NO_DE preCATED
使用空间boost ::文件系统;
使用命名空间std;布尔find_file(const的路径和放大器; dir_path,//在此目录中,
常量标准::字符串&安培; FILE_NAME,//搜索这个名字,
路径和放大器; path_found)//将路径这里若发现
{
如果(!存在(dir_path))返回false;
directory_iterator end_itr; //默认构造生成一个结束
对于(directory_iterator ITR(dir_path);
ITR = end_itr!;
++ ITR)
{
如果(is_directory(itr->状态()))
{
如果(find_file(itr->路径(),FILE_NAME,path_found))返回true;
}
否则,如果(itr-方式>路径()文件名()== FILE_NAME)//见下文
{
path_found = itr->路径();
返回true;
}
}
返回false;
}诠释的main()
{
路径mypath中=C:;
字符串MYFILE =名为.doc;
路径myfound =C:; find_file(mypath中,MYFILE,myfound);
}
我也试过这code,但它不会编译它表明这个错误和大量
未定义的参考`的boost :: filesystem3 ::路径::文件名()const的
还有:
X:\\ MinGW的\\提升\\ boost_1_47_0 \\提升\\系统\\错误_ code.hpp | 214 |未定义的参考`的boost ::系统:: generic_category()|
您必须对boost_system和boost_filesystem库链接。如何做到这一点取决于你的编译器/连接组合;例如,我的系统上我要补充标志 -lboost_system-MT -lboost_filesystem-MT
。
一些言论:在Windows上,通常希望 wstring的
(或其他宽字符对象),以提高您使用UNI code路径的工作机会。其次,你可以让你的code。使用更短的 find_if
和 recursive_directory_iterator
:
的#include<&算法GT;
#包括LT&;&iostream的GT;#定义BOOST_FILESYSTEM_NO_DE preCATED
#定义BOOST_FILESYSTEM_VERSION 3#包括LT&;升压/ filesystem.hpp>使用命名空间std;
使用空间boost ::文件系统;布尔find_file(const的路径和放大器; dir_path,常量路径和放大器; FILE_NAME,路径和放大器; path_found){
常量recursive_directory_iterator结束;
const的自动IT = find_if(recursive_directory_iterator(dir_path),最后,
[&安培;文件名](常量directory_entry急症){
返回e.path()文件名()== FILE_NAME。
});
如果(它==结束){
返回false;
}其他{
path_found = IT->路径();
返回true;
}
}诠释主(){
常量路径mypath中= L在/ usr /地方;
常量路径MYFILE = Lfilesystem.hpp
路径myFound;
find_file(mypath中,MYFILE,myFound);
wcout<< myFound<< ENDL;
}
我的示例使用C ++ 11的特性汽车
和的λ
,这是在GCC present 4.6。如果你的编译器缺乏这些,你可以很容易地通过一个predicate对象和自动更换的λ
通过明确的类型说明:
的#include<功能>类file_name_equal:公共unary_function<路径,布尔> {
上市:
明确file_name_equal(const的路径和放大器; FNAME):FILE_NAME(FNAME){} 布尔运算符()(常量directory_entry&安培;输入)const的{
返回entry.path()文件名()== FILE_NAME。
}私人的:
路径FILE_NAME;
};布尔find_file_cxx03(const的路径和放大器; dir_path,常量路径和放大器; FILE_NAME,
路径和放大器; path_found){
常量recursive_directory_iterator结束;
常量recursive_directory_iterator它=
find_if(recursive_directory_iterator(dir_path),最后,
file_name_equal(FILE_NAME));
如果(它==结束){
返回false;
}其他{
path_found = IT->路径();
返回true;
}
}
另外一个不错的变种摆脱使用Boost.Optional返回值参考的:
...
#包括LT&;升压/ optional.hpp>使用命名空间std;
使用名字空间boost;
使用空间boost ::文件系统;可选<路径> find_file(const的路径和放大器; dir_path,常量路径和放大器; FILE_NAME){
常量recursive_directory_iterator结束;
const的自动IT = find_if(recursive_directory_iterator(dir_path),最后,
[&安培;文件名](常量directory_entry急症){
返回e.path()文件名()== FILE_NAME。
});
回吧==结束了吗?可选<路径>():它 - >路径();
}诠释主(){
常量路径mypath中= L在/ usr /地方;
常量路径MYFILE = Lfilesystem.hpp
wcout<< find_file(mypath中,MYFILE).get_value_or(找不到)<< ENDL;
}
I want to create an application that search files in directory and in subdirectory using the boost library for c++ also I don't want to get trouble with UNICODE files like files named arabic . So how can i do that?
UPDATE:
#include <iostream>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#define BOOST_FILESYSTEM_NO_DEPRECATED
using namespace boost::filesystem;
using namespace std;
bool find_file( const path & dir_path, // in this directory,
const std::string & file_name, // search for this name,
path & path_found ) // placing path here if found
{
if ( !exists( dir_path ) ) return false;
directory_iterator end_itr; // default construction yields past-the-end
for ( directory_iterator itr( dir_path );
itr != end_itr;
++itr )
{
if ( is_directory(itr->status()) )
{
if ( find_file( itr->path(), file_name, path_found ) ) return true;
}
else if ( itr->path().filename() == file_name ) // see below
{
path_found = itr->path();
return true;
}
}
return false;
}
int main()
{
path myPath = "C:";
string myFile = ".doc";
path myfound = "c:";
find_file(myPath, myFile, myfound);
}
I tried also this code but it won't compile it show this error and a lot
undefined reference to `boost::filesystem3::path::filename() const
also:
X:\mingw\boost\boost_1_47_0\boost\system\error_code.hpp|214|undefined reference to `boost::system::generic_category()'|
You have to link against the boost_system and the boost_filesystem libraries. How to do this depends on your compiler/linker combination; for example, on my system I have to add the flags -lboost_system-mt -lboost_filesystem-mt
.
Some remarks: On Windows, you usually want wstring
(or other "wide character" object) to increase your chance of working with Unicode paths. Second, you can make your code much shorter using find_if
and 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;
}
My example uses the C++11 features auto
and lambda
, which are present in GCC 4.6. If your compiler lacks these, you can easily replace the lambda by a predicate object and the auto
by an explicit type specifier:
#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;
}
}
Another nice variant gets rid of the return value reference using 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;
}
这篇关于在目录和子目录中搜索文件,使用Boost库C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!