c++11 boost文件系统操作

2018-07-13 11:04:11

filesystem 库是一个可移植的文件系统操作库,已被c++17标准收录。

注意编译时带上 libboost_system.so 和 libboost_filesystem.so 动态库,否则会报如下错。

main.cpp:(.text+0x18b): undefined reference to `boost::filesystem::path::operator/=(char const*)'
/tmp/ccboulJT.o: In function `case3()':
main.cpp:(.text+0x43b): undefined reference to `boost::filesystem::portable_posix_name(std::string const&)'
main.cpp:(.text+0x467): undefined reference to `boost::filesystem::windows_name(std::string const&)'
main.cpp:(.text+0x4d9): undefined reference to `boost::filesystem::portable_name(std::string const&)'
main.cpp:(.text+0x5c9): undefined reference to `boost::filesystem::portable_directory_name(std::string const&)'
main.cpp:(.text+0x6b6): undefined reference to `boost::filesystem::portable_file_name(std::string const&)'
main.cpp:(.text+0x921): undefined reference to `boost::filesystem::path::parent_path() const'
main.cpp:(.text+0x96a): undefined reference to `boost::filesystem::path::stem() const'
main.cpp:(.text+0x9b3): undefined reference to `boost::filesystem::path::filename() const'
main.cpp:(.text+0x9fc): undefined reference to `boost::filesystem::path::extension() const'
main.cpp:(.text+0xac5): undefined reference to `boost::filesystem::path::root_name() const'
main.cpp:(.text+0xb0e): undefined reference to `boost::filesystem::path::root_directory() const'
main.cpp:(.text+0xb57): undefined reference to `boost::filesystem::path::root_path() const'
main.cpp:(.text+0xc33): undefined reference to `boost::filesystem::path::replace_extension(boost::filesystem::path const&)'
main.cpp:(.text+0xcc1): undefined reference to `boost::filesystem::path::remove_filename()'


/usr/bin/ld: /tmp/ccqMaIe2.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/local/lib/boost_1_65_1/libboost_system.so.1.67.0: error adding symbols: DSO missing from command line

例子-1

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
using namespace std;

#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
namespace fs = boost::filesystem;

void case1()
{
    path p1("./a_dir");
    path p2("/usr/local/lib");
    path p3("c:\\tmp\\test.text");
    path p4("d:/boost/boost/filesystem/");

    path p5;
    assert(p5.empty());

}

void case2()
{
    char str[] = "the path is (/root).";

    {
        path p(str + 13, str + 14);
        assert(!p.empty());

        p /= "etc";
        string filename = "xinetd.conf";
        p.append(filename.begin(), filename.end());
        cout << p << endl;
        cout << system_complete(p) << endl;
    }

    {
        path p(str + 13, str + 15);

        p += "etc";
        string filename = "xinetd.conf";
        p.concat(filename.begin(), filename.end());
        cout << p << endl;
    }

    path p("/::/*/?/<>");
}

void case3()
{
    string fname("w+abc.xxx");
    assert(!portable_posix_name(fname));
    assert(windows_name(fname));

    assert(!portable_name("w+()abc.txt")    && !portable_name("./abc"));
    assert(!portable_directory_name("a.txt") && portable_directory_name("abc"));
    assert( portable_file_name("a.bc") && !portable_file_name("y.conf"));

}

//////////////////////////////////////////
void case4()
{
    path p("/usr/local/include/xxx.hpp");

    cout << p.string() << endl;

    cout << p.parent_path() << endl;
    cout << p.stem() << endl;
    cout << p.filename() << endl;
    cout << p.extension() << endl;

    assert(p.is_absolute());
    assert(system_complete(p).is_absolute());

    cout << p.root_name() << endl;
    cout << p.root_directory() << endl;
    cout << p.root_path() << endl;

    assert(!p.has_root_name());
    assert( p.has_root_path());
    assert( p.has_parent_path());

    cout << p.replace_extension() << endl;
    cout << p.replace_extension("hxx") << endl;
    cout << p.remove_filename() << endl;

    path p1("/test/1.cpp");
    path p2("/TEST/1.cpp");
    path p3("/abc/1.cpp");

    assert(p1 != p2);
    assert(p2 < p3);

    p = "/boost/tools/libs";

    BOOST_FOREACH(auto& x , p)
    {
            cout << "["<< x << "]";
    }

}

void case5()
{
    path p("./test.txt");

    try
    {
        file_size(p);
    }
    catch(filesystem_error& e)
    {
        cout << e.path1() << endl;
        cout << e.what() << endl;
    }

}

//////////////////////////////////////////
void case6()
{
    assert(status("/dev/null").type()   == character_file);
    assert(status("/bin").type()    == directory_file);
    assert(status("/bin/sh").type()     == regular_file);

    assert((status("/bin/sh").permissions() & owner_exe) == owner_exe);

    path root = "/usr/local/include/boost";

    assert( is_directory(root));
    assert(!exists(root/"nofile"));
    assert(!is_symlink(root/"version.hpp"));
    assert(!is_other(root/"version.hpp"));
    assert( is_regular_file(root/"version.hpp"));
    assert(!fs::is_empty(root/"version.hpp"));

}

void case7()
{
	cout << "\ncase7:\n";
    cout << initial_path() << endl;  //输出初始路径
    cout << current_path() << endl;  //输出当前路径

    // generate a temp file for test
    std::ofstream("./test.txt") << "abcd" << std::endl;

    //path p("/usr/local/include/boost/version.hpp");
    path p("./test.txt");
    cout << file_size(p) << endl;

    time_t t = last_write_time(p);
    last_write_time(p, time(0));

    (void)t;
}

//磁盘空间分配情况
#include <boost/ratio.hpp>
void case8()
{
    using namespace boost;
    //const int GBYTES = 1000*1000*1000;          //GB,不是GiB
    space_info si = space("/root");
    cout << si.capacity / giga::num<< endl;  //总空间G
    cout << si.available / giga::num<< endl; //可用
    cout << si.free / giga::num<< endl;      //空闲
}

void case9()
{
    //namespace fs = boost::filesystem;

    path ptest = "./test";
    if (exists(ptest))
    {
        if (fs::is_empty(ptest))
        {
            remove(ptest); //只能删除文件或空目录
        }
        else
        {
            remove_all(ptest);  //递归删除,危险
        }
    }

    assert(!exists(ptest));
    create_directory(ptest) ;  //创建目录

    copy_file("/usr/local/include/boost/version.hpp", ptest / "a.txt");
    assert(exists(ptest / "a.txt"));

    rename(ptest / "a.txt", ptest / "b.txt");
    assert(exists(ptest / "b.txt"));

    create_directories(ptest / "sub_dir1" / "sub_dir1");  //创建多层目录
}

void case10()
{

    typedef std::pair<directory_iterator, directory_iterator> dir_range;
    dir_range dr(directory_iterator("/tmp"),directory_iterator());

    BOOST_FOREACH(auto& x , dr)
    {      cout << x << endl;       }

	cout << endl << endl;

	//迭代目录
    typedef recursive_directory_iterator rd_iterator;
    rd_iterator  end;
    for (rd_iterator pos("/tmp");pos != end; ++pos)
    {
        cout << "level" << pos.level() << ":" <<*pos << endl;
    }


}


int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    case8();
    //case9();
    //case10();
}
[root@192 c++]# g++ -std=c++11 main.cpp -lboost_system -lboost_filesystem -L /usr/local/lib/boost_1_65_1/
[root@192 c++]# ./a.out 
"/etc/xinetd.conf"
"/etc/xinetd.conf"
"/retcxinetd.conf"
/usr/local/include/xxx.hpp
"/usr/local/include"
"xxx"
"xxx.hpp"
".hpp"
""
"/"
"/"
"/usr/local/include/xxx"
"/usr/local/include/xxx.hxx"
"/usr/local/include"
["/"]["boost"]["tools"]["libs"]
case7:
"/root/c++"
"/root/c++"
5
18
10
10


例子-2

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
using namespace std;

#include <boost/optional.hpp>
#include <boost/utility/string_ref.hpp>

#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
using namespace boost;
using namespace boost::filesystem;
namespace fs = boost::filesystem;

typedef recursive_directory_iterator rd_iterator;

//在特定目录查找文件
optional<path>
find_file(const path& dir, const string& filename){
    typedef optional<path> result_type;
    if (!exists(dir) ||!is_directory(dir))
    {   return result_type();   }

    rd_iterator end;
    for (rd_iterator pos(dir);pos != end; ++pos)
    {
        if(!is_directory(*pos) &&
                pos->path().filename() == filename)
        {   return result_type(pos->path());    }
    }

    return result_type();
}

void case1()
{
    auto r = find_file("/usr/local/lib/boost_1_65_1/", "libboost_system.so");

    if (r)
    {   cout << *r << endl; }
    else
    {   cout << "file not found." << endl;  }
}

//利用正则表达式查找文件
#include <boost/xpressive/xpressive_dynamic.hpp>
#include <boost/algorithm/string.hpp>
using namespace boost::xpressive;

vector<path> find_files(const path& dir, const string& filename)
{
    static xpressive::sregex_compiler rc;
    if (!rc[filename].regex_id())
    {
        string str = replace_all_copy(
                replace_all_copy(filename, ".", "\\."),
                "*", ".*");
        rc[filename] = rc.compile(str);
    }
	
	//返回类型
    typedef vector<path> result_type;
    result_type v;

    if (!exists(dir) || !is_directory(dir))
    {   return v;    }

    rd_iterator end;
    for (rd_iterator pos(dir);pos != end; ++pos)
    {
        if(!is_directory(*pos) &&
                regex_match(pos->path().filename().string(), rc[filename]))
        {
            v.push_back(pos->path());
        }
    }

    return v;
}

void case2()
{
    auto v = find_files("/usr/local/lib/boost_1_65_1/", "libboost_math_*");
    cout << v.size() << endl;

    for(path &p : v)
    {   cout << p << endl;  }

}

//复制文件
#include <boost/progress.hpp>

size_t copy_files(const path& from_dir, const path& to_dir ,
                    const string& filename = "*")
{
    if (!is_directory(from_dir))
    {
        cout << "args is not a dir." << endl;
        return 0;
    }

    cout << "prepare for copy, please wait..." << endl;

    auto v = find_files(from_dir, filename);
    if (v.empty())
    {
        cout << "0 file copied." << endl;
        return 0;
    }

    cout << "now begin copy files ..." << endl;
    path tmp;
    progress_display pd(v.size());

    for(auto& p : v)
    {
        tmp = to_dir / p.string().substr(from_dir.string().length());
        if (!exists(tmp.parent_path()))
        {
            create_directories(tmp.parent_path());
        }
        copy_file(p, tmp);
        ++pd;
    }

    cout << v.size() << " file copied." << endl;
    return v.size();
}

void case3()
{
    copy_files("/etc/cron.d", "./tmp");
}

//文件流操作
#include <boost/filesystem/fstream.hpp>
namespace newfs = boost::filesystem;

void case4()
{
    path p("./test.txt");
    newfs::ifstream ifs(p);
    assert(ifs.is_open());
    cout << ifs.rdbuf();

    // remove file
    ifs.close();
    remove(p);
}

int main()
{
    case1();
    case2();
    case3();
    case4();
}
[root@192 c++]# g++ -std=c++11 main.cpp -lboost_system -lboost_filesystem \
                    -L /usr/local/lib/boost_1_65_1/
[root@192 c++]# ./a.out 
"/usr/local/lib/boost_1_65_1/libboost_system.so"
18
"/usr/local/lib/boost_1_65_1/libboost_math_c99.a"
"/usr/local/lib/boost_1_65_1/libboost_math_c99f.a"
"/usr/local/lib/boost_1_65_1/libboost_math_c99f.so"
...
prepare for copy, please wait...
now begin copy files ...

0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
2 file copied.
abcd


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/af


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。