boost::filesystem文件操作

#include <boost/filesystem.hpp>
#include <iostream>
#include <boost/ratio.hpp>
#include <map>
#include <vector>
#include <string>
#include <memory>
#include <boost/optional.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/progress.hpp>

/**********************************************************
*使用boost::filesystem::director_iterator迭代当前目录下文件(不向下层目录迭代),但是也可实现目录下层目录循环递归,
*其实boost也提供了boost::filesystem::recursive_directory_iterator向下递归而且遍历目录是可控制的(深度/浅度),
*且速度比递归的director_itertaor快
***********************************************************/
void resource_direction(const boost::filesystem::path& path)
{
    //递归文件目录下的所有文件路径
    boost::filesystem::directory_iterator end;
    for(boost::filesystem::directory_iterator begin(path);begin!=end;begin++)
    {
        //如果是目录继续向下解析
        if (boost::filesystem::is_directory(*begin))
            resource_direction(*begin);
        else
            std::cout<<*begin<<std::endl;
    }
}

//boost filesystem realize find file
boost::optional<boost::filesystem::path> find_file(const boost::filesystem::path& path,const std::string& file)
{
    typedef boost::optional<boost::filesystem::path> result_value;
    if (!boost::filesystem::exists(path)&&!boost::filesystem::is_directory(path))
        return result_value();

    //递归目录查找
    boost::filesystem::recursive_directory_iterator end;
    for(boost::filesystem::recursive_directory_iterator iter(path);iter!=end;++iter)
    {
        if (!boost::filesystem::is_directory(*iter)&&iter->path().filename()==file)
            return result_value(iter->path());
    }

    return result_value();
}

//boost filesystem realize obscure find file 利用boost::xpressive正则匹配实现模糊查找(只实现"*"匹配)
std::vector<boost::filesystem::path> obscure_find_file(const boost::filesystem::path &path, const std::string &file)
{
    //之后查找使用- -
    static boost::xpressive::sregex_compiler rc;         //正则表达式工厂
    if (!rc[file].regex_id())
    {
        std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\\."), "*", ".*");
        rc[file] = rc.compile(str);
    }


    typedef std::vector<boost::filesystem::path> result_value;
    result_value v;
    if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path))
    {
        return v;
    }

    //递归目录查找
    boost::filesystem::recursive_directory_iterator end;
    for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter)
    {
        if (!boost::filesystem::is_directory(*iter) &&
            boost::xpressive::regex_match(iter->path().filename().string(), rc[file]))
        {
            v.push_back(iter->path());
        }
    }

    return v;
}

std::size_t copy_files(const boost::filesystem::path &from_dir,  const boost::filesystem::path &to_dir,
                        const std::string &filename = "*")
{
    if (!boost::filesystem::exists(from_dir))
    {
        std::cout << "file not find" << std::endl;
        return -1;
    }


    std::cout << "prepare copy please wait....." << std::endl;
    auto vcontain = obscure_find_file(from_dir, filename);

    if (vcontain.empty())
    {
        std::cout << "file is empty" << std::endl;
        return -1;
    }


    boost::filesystem::path temp;
    boost::progress_display display(vcontain.size());

    for (auto &iter:vcontain)
    {
        temp = to_dir / iter.string().substr(from_dir.string().length());
        std::cout << "file: " << temp << std::endl;
        if (!boost::filesystem::exists(temp.parent_path()))
        {
            boost::filesystem::create_directories(temp.parent_path());
        }

        if(boost::filesystem::is_directory(iter))
        {
            boost::filesystem::create_directories(temp);
        }
        else{
            boost::filesystem::copy_file(iter, temp, boost::filesystem::copy_option::overwrite_if_exists);
        }

        ++display;
    }

    std::cout << vcontain.size() << " filed copyed" << std::endl;

    return vcontain.size();

}


int main()
{
    //filesystem basic
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        //unix
        boost::filesystem::path path1("./Demo/Demo.txt");
        //windows
        boost::filesystem::path path2("C:\\Boost\\Demo\\include\\");

        //空路径,可用empty()判断
        boost::filesystem::path path3;
        assert(path3.empty());

        //path构造时不会检查路径的合法性(可使用函数判断)
        boost::filesystem::path path4("asdwqdqdasd");


        boost::filesystem::path path5("/usr/local/include/");
        auto path6 = path5 / "boost/filesystem/";                    //path重载了operator/()方法可追加路径
        std::cout << path6 << std::endl;                             //path重载operator<<方法输出
        std::cout << path6.string() << std::endl;                    //返回string的方法,可用于C++中的fstream
        std::cout << path6.parent_path() << std::endl; //父路径
        std::cout << path6.filename() << std::endl; //文件
        std::cout << path6.stem() << std::endl; //不带扩展名的文件名
        std::cout << path6.extension() << std::endl; //扩展名


        //唯一两个可修改路径函数
        path6.replace_extension("ini");     //修改文件后缀名
        std::cout << path6 << std::endl;                    //"/usr/local/include/boost/filesystem/.ini"
        path6.remove_filename();            //移除文件名
        std::cout << path6 << std::endl;                    //"/usr/local/include/boost/filesystem"

        //path中有begin 和 end 迭代器,可以循环得出目录名
        for (auto &iter:path6)
        {
            std::cout << "[" << iter << "]" << std::endl;
        }
        /*["/"]
          ["usr"]
          ["local"]
          ["include"]
          ["boost"]
          ["filesystem"]*/
        //    for (boost::filesystem::path::iterator it = path6.begin(); it != path6.end(); ++it)
        //        std::cout << *it << std::endl;
        //    //path6 /= "/home/kerngeeksund/Documents";//将一个路径添加到另一个之上 p /= path dengtongyu p = p / path
        //    std::cout << p.string() << std::endl;


        enum file_type
        {
            status_error,
        #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
            status_unknown = status_error,
        #endif
            file_not_found,
            regular_file,
            directory_file,
            // the following may not apply to some operating systems or file systems
                    symlink_file,
            block_file,
            character_file,
            fifo_file,
            socket_file,
            reparse_file,  // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink
            type_unknown,  // file does exist, but isn't one of the above types or
            // we don't have strong enough permission to find its type

            _detail_directory_symlink  // internal use only; never exposed to users
        };

        std::cout << boost::filesystem::status(path6).type() << std::endl;              //文件类型
        std::cout << boost::filesystem::symlink_status(path6).type() << std::endl;
        std::cout << boost::filesystem::directory_file << std::endl;
        std::cout << boost::filesystem::status(path6).permissions() << std::endl;      //文件的权限等级
    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //    查看磁盘和当前路径,修改文件时间(linux::touch)
    //    因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        boost::filesystem::path path("/Users/xuaidong/Desktop/test.txt");
        boost::filesystem::path path1("/Users/xuaidong");
        //进入(程序启动时)main函数时的路径
        std::cout << boost::filesystem::initial_path() << std::endl;
        //返回当前路径,和initial_path()都是返回绝对路径(完整路径)
        std::cout << boost::filesystem::current_path() << std::endl;

        assert(boost::filesystem::is_regular_file(path));

        //返回文件最后一次修改时间
        std::cout << boost::filesystem::last_write_time(path) << std::endl;
        //更改文件修改时间(linux touch)
        boost::filesystem::last_write_time(path, time(0));
        std::cout << boost::filesystem::last_write_time(path) << std::endl;

        //查看磁盘空间
        boost::filesystem::space_info sp = boost::filesystem::space(path);
        std::cout << "磁盘空间: " << sp.capacity / boost::giga::num << std::endl;
        std::cout << "磁盘可用空间: " << sp.free / boost::giga::num << std::endl;
        std::cout << "磁盘可用空间: " << sp.available / boost::giga::num << std::endl;

        std::cout << boost::filesystem::file_size(path) << std::endl;
    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //创建目录,删除目录,拷贝文件
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        boost::filesystem::path path("/Users/xuaidong/Desktop/ABABAB");

        //assert(boost::filesystem::is_regular_file(path));
        assert(boost::filesystem::is_directory(path));

        //删除空目录/文件
        //boost::filesystem::remove(path);
        //递归删除多个目录或者文件
        boost::filesystem::remove_all(path);


        //根据path创建一个目录
        boost::filesystem::create_directories(path);
        assert(boost::filesystem::exists(path));
        //拷贝文件到这个目录下
        boost::filesystem::copy_file("/Users/xuaidong/Desktop/Some.txt", path / "Some2.txt");

        //重命名
        boost::filesystem::rename(path/"Some2.txt",path/"Demo.txt");

        //创建多及目录
        boost::filesystem::create_directories(path/"Director1"/"Director2"/"Director3");


    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //遍历目录
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        boost::filesystem::path path("/Users/xuaidong/Desktop/");
        resource_direction(path);

    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //系统提供的文件目录遍历
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        std::map<int64_t, std::shared_ptr<std::vector<std::string>>> dir_map;
        //boost深度遍历目录和浅度遍历
        //默认构造是尾迭代器
        boost::filesystem::recursive_directory_iterator end;
        for (boost::filesystem::recursive_directory_iterator iter("/Users/xuaidong/Desktop"); iter != end; iter++)
        {
            //std::cout << "directory_level: " << iter.level() << "file path: " << *iter << std::endl;
            if (boost::filesystem::is_directory(*iter))
            {
                iter.no_push();
            }             //不深度便利
            //iter.pop() 退出当前目录的遍历

            auto &ptr = dir_map[iter.level()];
            if (!ptr)
                ptr.reset(new std::vector<std::string>);

            ptr->push_back(iter->path().string());

        }

        for (auto &iter1:dir_map)
        {
            for (auto &iter2:*(iter1.second))
            {
                std::cout << "directory_level: " << iter1.first << ", file path: " << iter2 << std::endl;
            }
        }

    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //实现简单文件查找
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        auto path=find_file("/Users/xuaidong/Desktop/","application.cpp");

        if (path)
        {
            std::cout<<"CMakeLists.txt is here: "<<*path<<std::endl;
        }else
        {
            std::cout<<"CMakeLists.txt not to find"<<std::endl;
        }

    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //利用boost::xpressive正则匹配实现模糊查找(只实现"*"匹配)
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        auto path = obscure_find_file("/home/kerngeeksund/Documents/", "*.txt");
        for (auto &iter:path)
        {
            std::cout << "file match: " << iter << std::endl;
        }
    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    //实现目录文件拷贝(空目录也拷贝)
    //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理
    try
    {
        copy_files("/home/kerngeeksund/Documents/Test1", "/home/kerngeeksund/Documents/Test2");
    }
    catch (boost::filesystem::filesystem_error &e)
    {
        std::cout << e.path1() << std::endl;
        std::cout << e.path2() << std::endl;
        std::cout << e.what() << std::endl;
    }

    return 0;

}

猜你喜欢

转载自blog.csdn.net/sunlin972913894/article/details/103537094