使用boost库c ++在目录和子目录中搜索文件 [英] Search files in directory and subdirectory using boost library c++
问题描述
我想创建一个应用程序,搜索文件在目录和子目录使用boost库的c + +,我也不想遇到UNICODE文件像阿拉伯文件的麻烦。
那么我该怎么做呢?
UPDATE: $ p> #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,//在此目录中,
const std :: string& file_name,//搜索此名称,
路径& path_found)//如果找到则放置路径
{
if(!exists(dir_path))return false;
directory_iterator end_itr; //默认构造产生过去的结束
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)//见下面
{
path_found = itr-> path
return true;
}
}
return false;
}
int main()
{
path myPath =C:;
string myFile =.doc;
path myfound =c:;
find_file(myPath,myFile,myfound);
}
我也试过这个代码,但它不会编译它显示此错误,很多
未定义引用`boost :: filesystem3 :: path :: filename()const
也:
X: \mingw\boost\boost_1_47_0\boost\system\error_code.hpp | 214 |未定义引用`boost :: system :: generic_category()'|
解决方案您必须链接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 ;
});
if(it == end){
return false;
} else {
path_found = it-> path();
return true;
}
}
int main(){
const path myPath = L/ usr / local;
const path myFile = Lfilesystem.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;
可选< 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 ;
});
return it == end?可选< path>():it-> path();
}
int main(){
const path myPath = L/ usr / local;
const path myFile = Lfilesystem.hpp;
wcout<< find_file(myPath,myFile).get_value_or(not found)< 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 usingfind_if
andrecursive_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
andlambda
, which are present in GCC 4.6. If your compiler lacks these, you can easily replace the lambda by a predicate object and theauto
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屋!