C++使用BOOST操做文件、目錄

開始使用

在BOOST庫出現以前,C++對於文件和目錄的操做,大都藉助於UNIX提供的底層文件和目錄接口,從使用角度來看,這些底層的操做不夠友好。BOOST中filesystem庫是一種可移植的文件系統操做庫,能夠跨平臺的操做目錄、文件等,在不失性能的狀況下,提供了友好的操做方法。 
本文主要介紹在UNIX環境中,boost::filesystem的經常使用操做方法。 
假設你已經安裝好了boost庫,使用boost::filesystem須要加上頭文件windows

#include <boost/filesystem.hpp>

編譯時,須要連接ruby

-lboost_filesystem

當安裝路徑不是UNIX環境變量中設置的標準路徑的話,編譯時還需加上boost庫頭文件和動態路路徑,即:函數

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

變量$(BOOST)是BOOST庫實際安裝路徑。性能

filesystem介紹

filesystem庫是一個可移植的文件系統操做庫,它在底層作了大量的工做,使用POSIX標準表示文件系統的路徑,使C++具備了相似腳本語言的功能,能夠跨平臺操做目錄、文件,寫出通用的腳本程序。ui

1.path的構造函數能夠接受C字符串和string,也能夠是一個指定首末迭代器字符串序列區間。spa

2.filesystem提供了一系列的文件名(或目錄)檢查函數。code

3.有豐富的函數用於獲取文件名、目錄名、判斷文件屬性等等。對象

4.filesystem庫使用異常來處理文件操做時發生的錯誤。blog

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;      // 相對路徑:Windows\System32\services.exe
    std::cout << dir.parent_path()<< std::endl;        //上級目錄:C:\Windows\System32
    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操做時加上異常捕獲,也可以增長代碼的魯棒性,在此不進行累述。

相關文章
相關標籤/搜索