• C++使用BOOST操作文件、目录


    开始使用

    在BOOST库出现之前,C++对于文件和目录的操作,大都借助于UNIX提供的底层文件和目录接口,从使用角度来看,这些底层的操作不够友好。BOOST中filesystem库是一种可移植的文件系统操作库,可以跨平台的操作目录、文件等,在不失性能的情况下,提供了友好的操作方法。 
    本文主要介绍在UNIX环境中,boost::filesystem的常用操作方法。 
    假设你已经安装好了boost库,使用boost::filesystem需要加上头文件

    #include <boost/filesystem.hpp>

    编译时,需要链接

    -lboost_filesystem

    当安装路径不是UNIX环境变量中设置的标准路径的话,编译时还需加上boost库头文件和动态路路径,即:

    -I $(BOOST)/include/
    -L $(BOOST)/lib/

    变量$(BOOST)是BOOST库实际安装路径。

    filesystem介绍

    filesystem库是一个可移植的文件系统操作库,它在底层做了大量的工作,使用POSIX标准表示文件系统的路径,使C++具有了类似脚本语言的功能,可以跨平台操作目录、文件,写出通用的脚本程序。

    1.path的构造函数可以接受C字符串和string,也可以是一个指定首末迭代器字符串序列区间。

    2.filesystem提供了一系列的文件名(或目录)检查函数。

    3.有丰富的函数用于获取文件名、目录名、判断文件属性等等。

    4.filesystem库使用异常来处理文件操作时发生的错误。

    5.filesystem库提供一个文件状态类file_status及一组相关函数,用于检查文件的各种属性,如是否存在、是否是目录、是否是符号链接等。

    6.filesystem提供了少量的文件属性操作,如windows下的只读、归档等,Linux下的读写权限等。

    7.文件操作,如创建目录、文件改名、文件删除、文件拷贝等等。

    8.basic_directory_iterator提供了迭代一个目录下所有文件的功能。

    path类的基本用法

     //注意 /= 和 += 的区别, /= 表示追加下级目录, +=  仅仅是字符串的串接 
        path dir("C:\Windows");
        dir /= "System32";       //追加下级目录
        dir /= "services.exe";
        std::cout << dir << std::endl;
        std::cout << dir.string() << std::endl;            //转换成std::string 类型
        std::cout << dir.root_name()<< std::endl;          //盘符名:C:
        std::cout << dir.root_directory()<< std::endl;     //根目录:""
        std::cout << dir.root_path()<< std::endl;          //根路径:"C:"
        std::cout << dir.relative_path()<< std::endl;      // 相对路径:WindowsSystem32services.exe
        std::cout << dir.parent_path()<< std::endl;        //上级目录:C:WindowsSystem32
        std::cout << dir.filename()<< std::endl;           //文件名:services.exe
        std::cout << dir.stem()<< std::endl;               //不带扩展的文件名:services
        std::cout << dir.extension()<< std::endl;          //扩展名:.exe

    常用函数及异常处理

    system_complete(path);//  返回完整路径(相对路径+当前路径) 
    exists(path);//  目录是否存在 
    is_directory(path);// 
    is_directory(file_status);//  是否是路径 
    is_regular_file(path);// 
    is_regular_file(file_status);//  是否是普通文件 
    is_symlink(path);// 
    is_symlink(file_status);//  是否是一个链接文件 
    file_status status(path);//  返回路径名对应的状态 
    initial_path();//  得到程序运行时的系统当前路径 
    current_path();//  得到系统当前路径 
    current_path(const Path& p);//  改变当前路径 
    space_info space(const Path& p);// 得到指定路径下的空间信息,space_info 有capacity, free 和 available三个成员变量,分别表示容量,剩余空间和可用空间。 
    last_write_time(const Path& p);//  最后修改时间 
    last_write_time(const Path& p, const std::time_t new_time);// 修改最后修改时间 
    bool create_directory(const Path& dp);//  建立路径 
    create_hard_link(const Path1& to_p, const Path2& from_p);// 
    error_code create_hard_link(const Path1& to_p, const Path2& from_p, error_code& ec);// 建立硬链接 
    create_symlink(const Path1& to_p, const Path2& from_p);// 
    create_symlink(const Path1& to_p, const Path2& from_p, error_code& ec);// 建立软链接 
    remove(const Path& p, system::error_code & ec = singular );//  删除文件 
    remove_all(const Path& p);//   递归删除p中所有内容,返回删除文件的数量 
    rename(const Path1& from_p, const Path2& to_p);//  重命名 
    copy_file(const Path1& from_fp, const Path2& to_fp);//  拷贝文件 
    omplete(const Path& p, const Path& base=initial_path<Path>());// 以base以基,p作为相对路径,返回其完整路径 
    create_directories(const Path & p);//  建立路径

    实例

    路径(path类)和迭代器–filesystem操作的基础 

    path类提供了路径操作的丰富接口,可以获得文件名、拓展名、文件属性等。迭代器提供了遍历整个目录所有文件的功能,常用的filesystem库的迭代器是:directory_iterator和recursive_directory_iterator,后者相对于前者提供了递归遍历的功能。

    基于路径和迭代器,下文已迭代目录(cur/)为例,简介filesystem的基本操作:

    首先,定义要处理文件的路径 
    string curPath = “/home/test/cur/” ; 
    条件假设: 
    1).cur目录下结构如下 
    cur/ 
    —build.sh 
    —src/ 
    ——main.cpp 
    ——makefile 
    2).进入/home/test/cur目录,执行build.sh编译程序后,留在当前目录执行可执行文件 
    3).假设程序扫描目录时,首先扫描到的文件时 build.sh

    //定义一个可以递归的目录迭代器,用于遍历
    boost::filesystem::recursive_directory_iterator itEnd;
    for(boost::filesystem::recursive_directory_iterator itor( curPath.c_str() ); itor != itEnd ;++itor)
    {
        //itor->path().string()是目录下文件的路径
        /*
         *当curPath是相对路径时,itor->string()也是相对路径
         *即当curPath = "../cur/",下面将输出"../cur/build.sh"
         */
        //当curPath是绝对路径时,itor->string()也是绝对路径
        string file =  itor->path().string() ; // "/home/test/cur/build.sh"
    
        //构造文件路径,以获得文件丰富的操作
        //path可以接受C风格字符串和string类型作为构造函数的参数,而提供的路径可以是相对路径,也可以是绝对路径。
        boost::filesystem::path filePath(file);
        //path的方法如filename()等,返回的对象仍是path,如果可以通过path的string()方法,获取对象的string类型
        //parent_path()获得的是当前文件的父路径
        cout<<filePath.parent_path()<<endl;  // "/home/test/cur/"
    
        //filename()获得的是文件名,含拓展名
        cout<<filePath.filename()<<endl;  // "build.sh"
        cout<<filePath.filename().string()<<endl;
    
        //stem()获得的是文件的净文件名,即不含拓展名
        cout<<filePath.stem()<<endl; // "build"
    
        //extension()文件的拓展名(主要是".sh"而不是"sh")
        cout<<filePath.extension()<<endl; // ".sh"
    
        //获得文件的大小,单位为字节
        int nFileSize = boost::filesystem::file_size(filePath);
    
        //最后一次修改文件的时间
        //last_write_time()返回的是最后一次文件修改的绝对秒数
        //last_write_time(filePath,time(NULL))还可以修改文件的最后修改时间,相当于Linux中命令的touch
        if(filePath.last_write_time() - time(NULL) > 5)
        {
            /*
             *在工程实践中,当需要不断的扫目录,而目录又会不断的加入新文件时,
             *借助last_write_time()可以判断新入文件的完整性,以避免错误的处理还未写完的文件
             */
        }
    
        //判断文件的状态信息
        if(boost::filesystem::is_regular_file(file))
        {
            //is_regular_file(file)普通文件
            //is_directory(file)目录文件,如当遍历到"/home/test/cur/src/"时,这就是一个目录文件
            //is_symlink(file)链接文件
            ...
        }
    
        //更改拓展名
        boost::filesystem::path tmpPath = filePath;
        //假设遍历到了cpp文件,想看下对应的.o文件是否存在
        tmpPath.replace_extension(".o");
        //判断文件是否存在
        if( boost::filesystem::exists( tmpPath.string() ) )
    
        //删除文件
        //remove只能删除普通文件,而不能删除目录
        boost::filesystem::remove(tmpPath.string());
        //remove_all则提供了递归删除的功能,可以删除目录
        boost::filesystem::remove_all(tmpPath.string());
    
        //移动文件 & 拷贝文件
        //srcPath原路径,srcPath的类型为string
        //destPath目标路径,destPath的类型为string
        boost::filesystem::rename(srcPath , destPath);
        boost::filesystem::copy_file(srcPath , destPath);
        //拷贝目录
        boost::filesystem::copy_files("/home/test","/dev/shm")
    
    }
    
    boost::filesystem还可以创建目录:
    if( !boost::filesystem::exists( strFilePath ) )
    {
        boost::filesystem::create_directories(strFilePath)
    }

    boost::filesystem提供的操作当然不只如此,详见参考文件1。使用boost::filesystem操作时加上异常捕获,也能够增加代码的鲁棒性,在此不进行累述。

  • 相关阅读:
    在子Repeater调用父Repeater里的数据
    使用事务范围实现隐式事务
    关于TransactionScope分布式事务在Oracle下的运作
    C#枚举类型的使用示例
    ORACLE分区表发挥性能
    oracle 批处理 执行 sql
    连接查询_左连接/右连接/全连接的区别
    转: C#的25个基础概念
    bat文件编写
    Nginx 远程安全漏洞
  • 原文地址:https://www.cnblogs.com/aoyihuashao/p/9226032.html
Copyright © 2020-2023  润新知