boost.png (6897 bytes) Filesystem 庫
Boost Home    Library Home    Tutorial    Reference   FAQ
目錄
簡介
使用本庫
兩分鐘指南
警告
例子程序
實現

不再使用的名字和特性
只使用窄字符路徑
構建目標庫
    給 Cygwin 用戶的說明
鳴謝
變更歷史
其它文檔
參考
庫的設計
FAQ
可移植性指南
待辦事項

簡介

Boost.Filesystem 庫為對路徑、文件和目錄進行查詢和操作提供了可移植的工具。

本庫的動機源自以下需要,即在C++程序內部執行一些可移植的、類似於腳本的操作。它的意圖不是要和 Python, Perl,或 shell 語言進行競爭,而是在已經選定了C++作為開發語言的情況下,提供一些可移植的文件系統操作。在 設計 中我們鼓勵但不要求安全和可移植地使用它。

使用本庫的程序是可移植的,這意味著不僅程序代碼的語法是可移植的,而且代碼的語義和行為也是可移植的。通用路徑語法也是可移植性的一個重點。

使用本庫是安全的,意味著不可能忽略使用中發生的錯誤,由於其中大多數函數在檢測到錯誤時會拋出C++異常。這對於用戶來說也是很方便的,因為減少了通過返回碼檢查錯誤的需要。

提議 N1975 建議將 Boost.Filesystem 包含到 Technical Report 2 中,已經被C++標準委員會所接納。Boost.Filesystem 庫將保留在 TR2 Filesystem 建議書中,就像它在 TR2 的進程中那樣。不過請注意,Boost.Filesystem 和 TR2 建議書之間的名字空間和頭文件粒度會有所不同。

Boost.Filesystem 庫提供了以下幾個頭文件:

使用本庫

Boost.Filesystem 被實現為一個單獨編譯的庫,所以在使用它之前,你必須將它安裝在一個你的鏈接器可以查找到的地方。請見 構建目標庫

本庫的 example 目錄 包含了非常簡單的腳本,用於在不同平台上構建 例子程序。你可以用這些腳本來看一下,編譯和鏈接你自己的程序需要些什麼。

兩分鐘指南

(Tabrez Iqbal 還有一個 更詳盡的指南)

先來一些準備工作:

#include "boost/filesystem.hpp"   // 包含所有需要的 Boost.Filesystem 聲明
#include <iostream> // 使用 std::cout
using boost::filesystem; // 為了方便陳述;在真實代碼中使用名字空間別名是首選

然後可以創建一個 path 的對象:

path my_path( "some_dir/file.txt" );

傳遞給 path 構造函數的字符串可以是 可移植通用路徑格式 或是實現定義的原生操作系統格式。訪問函數使得 my_path 的內容可以以操作系統無關的格式來訪問底層的操作系統API,如 "some_dir:file.txt", "[some_dir]file.txt", "some_dir/file.txt", 或者任何適用於操作系統的格式。如果使用類 wpath 來替代類 path,則會在操作系統需要時自動執行寬字符與窄字符之間的轉換。

path 具有從 const char* const std:: string& 進行構造的構造函數,所以即使以下代碼片斷中所使用的 Filesystem 庫函數具有 const path& 形參,用戶也可以用C風格的字符串作為實參:

remove_all( "foobar" );
create_directory( "foobar" );
ofstream file( "foobar/cheeze" );
file << "tastes good!\n";
file.close();
if ( !exists( "foobar/cheeze" ) )
std::cout << "Something is rotten in foobar\n";

為了讓類 path 的對象更容易在表達式中使用,operator/ 被用來增加路徑:

ifstream file1( arg_path / "foo/bar" );
ifstream file2( arg_path / "foo" / "bar" );

表達式 arg_path / "foo/bar"arg_path / "foo" / "bar" 會得到相同的結果。

路徑中可以包含對當前目錄的引用,使用 "." 符號,還有父目錄的引用,使用 ".." 符號。

類 basic_directory_iterator 是本庫的一個重要組件。它提供了遍歷一個目錄內容的輸入迭代器,它的值類型是類 basic_path. Typedefs directory_iteratorwdirectory_iterator 被提供以覆蓋最常見的用例。

以下函數中,給定一個目錄路徑和一個文件名,在該目錄及其子目錄中遞歸查找該文件名,返回一個 bool, 並在成功時返回找到文件的路徑。以下代碼取自一個真實的程序,為清晰起見作了少許修改:

bool find_file( const path & dir_path,         // 在該目錄下,
const std::string & file_name, // 查找該文件名,
path & 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->leaf() == file_name ) // 見後
{
path_found = itr->path();
return true;
}
}
return false;
}

在註釋 // 見後 所在的那行代碼中,表達式 itr->path().leaf() == file_name,在迭代器所指的 directory_entry 對象的 path() 函數調用後所返回的 path 上再調用 leaf() 函數。leaf() 返回一個字符串,它是在 path 對像中的最後(最接近葉節點,離根節點最遠)的文件或目錄名的拷貝。

除了 leaf(), 還有其它幾個函數名使用了 樹tree/根root/分支branch/葉子leaf 的比喻。

注意,find_file() 並不顯式檢查錯誤,如驗證 dir_path 參數是否真的表示一個目錄。Boost.Filesystem 的函數在不同完全成功時會拋出異常,所以已經有了足夠的隱式錯誤檢查,應用程序無需提供額外的錯誤檢查代碼,除非你想要。有幾個 Boost.Filesystem 函數具有不拋出版本,可用於不適合使用異常的情況。

說明:在上述例子代碼寫完後,目錄的遞歸迭代被作為一個便利函數被增加到庫中,所以現在你不再需要自己編寫代碼來執行遞歸了。

警告

閱讀本指南後,你就可以使用 Filesystem 庫進行簡單的、類似腳本的編程了!不過在進行關鍵的工作之前,你還要知道幾個警告:

在出現競爭條件時結果與後續條件不被保證

Filesystem 的函數規範遵循C++標準的格式,以結果和後續條件來規定行為。如果存在 競爭條件race-condition,則函數的後續條件在函數返回到調用者時可能不再為真。

解釋:文件和目錄的狀態通常都是全局共享的,因而可能會被其它線程、進程或甚至通過網絡訪問該文件系統的其它計算機所修改。這一點可能會引起問題,以下就是一個這樣的例子,注意以下斷言可能失敗:

assert( exists( "foo" ) == exists( "foo" ) );  // (1)

remove_all( "foo" );
assert( !exists( "foo" ) );  // (2)

assert( is_directory( "foo" ) == is_directory( "foo" ) ); // (3)

(1) 可能失敗,如果在第一次和第二調用 exists() 之間,一個原本不存在的 "foo" 變為存在了,或者一個原本存在的 "foo" 被刪除。這是有可能發生的,如果在這個例子的執行過程中,另一個線程、進程或計算機也在同一個目錄下進行了操作。

(2) 可能失敗,如果在調用 remove_all() 和調用 exists() 之間,一個名為 "foo" 的新文件或新目錄被另一個線程、進程或計算機所創建。

(3) 可能失敗,如果另一個線程、進程或計算機在這個例子兩次調用 is_directory() 之間刪除了一個原本存在的文件 "foo",然後又創建一個名為 "foo" 的目錄。

可能拋出異常

除非特別說明,否則 Boost.Filesystem 的函數在不能成功完成它們的操作規範時,會拋出 basic_filesystem_error 異常。另外,實現可能會使用C++標準庫的函數,而後者可能拋出 std::bad_alloc. 即使錯誤條件所導致的異常沒有在函數的 "拋出" 節中明確給出,這些異常也可能會被拋出。

由 Filesystem 庫拋出的所有異常都是通過調用 boost::throw_exception() 來實現的。因此精確的行為可能會有所不同,其取決於 filesystem 源代碼編譯時的 BOOST_NO_EXCEPTIONS 設置。

有幾個函數提供了無拋出的版本,它們通常用在適合以錯誤代碼作為報告錯誤的方法的情形下。

例子程序

simple_ls.cpp

例子程序 simple_ls.cpp 以命令行參數給定一個路徑。因為命令行參數有可能是一個相對路徑,所以程序會計算出完整路徑,以使得顯示的信息更為精確。

該程序檢查該路徑是否存在;如果不存在則打印出一條信息。

如果該路徑表示一個目錄,則該目錄將被遍歷,並打印出目錄中的各條目名字,如果是目錄則還有一個標識。程序將更新一個目錄及文件的計數,並在遍歷結束後打印出來。

如果該路徑表示一個文件,則打印一條相應的信息。

請嘗試編譯和執行 simple_ls.cpp,看看它在你的系統上是如何工作的。試一下不同的路徑參數,看看有什麼發生。

file_size.cpp

如果給定的是一個普通文件,該例子程序將打印出文件的大小。

其它例子

以下程序使用 Filesystem 庫生成 Boost 回歸測試狀態表。請見:

有時候測試程序對於理解一個庫是非常有用的,因為它們示範了開發人員應該做什麼和不該做什麼。請見:

實現

當前的實現支持的操作系統包括 POSIX 和 Windows API.

該庫通常用於 Apple OS X, HP-UX, IBM AIX, Linux, Microsoft Windows, SGI IRIX, 和 Sun Solaris 操作系統,並使用多個不同編譯器。

如果需要,用戶可以定義以下宏。我們已提供了適當的缺省值,所以用戶可以忽略這些宏,除非他們有特殊的需要。

宏名稱 缺省值 作用
BOOST_WINDOWS_API 如果 Boost.System 的自動配置代碼檢測到 Windows,則被定義,否則不被定義。 實現使用 Microsoft Windows 的原生應用程序接口(API).
BOOST_POSIX_API 如果 Boost.System 的自動配置代碼未檢測到 Windows,則被定義。 實現使用 POSIX 的原生應用程序接口(API).
BOOST_FILESYSTEM_DYN_LINK 如果定義了 BOOST_ALL_DYN_LINK,則被定義,否則不被定義。 Boost.System 庫被動態鏈接。如果未定義,則假定為靜態鏈接。
BOOST_FILESYSTEM_NO_LIB 如果定義了 BOOST_ALL_NO_LIB,則被定義,否則不被定義。 Boost.System 庫不使用 Boost 自動鏈接工具。
BOOST_FILESYSTEM_NARROW_ONLY 不被定義。 移除需要 wchar_t 支持的特性。
BOOST_FILESYSTEM_NO_DEPRECATED 不被定義。 排除掉不再使用的特性。

不再使用的名字和特性

本庫隨著時間的發展,有些名字會改變,或者有些特性會被去除。為了易於轉變,Boost.Filesystem 建議不再使用舊的名字和特性,不過會繼續提供它們,除非定義了宏 BOOST_FILESYSTEM_NO_DEPRECATED

組件

舊名稱,現已不再使用

新名稱

basic_path leaf() filename()
basic_path branch_path() parent_path()
basic_path has_leaf() has_filename()
basic_path has_branch_path() has_parent_path()
basic_path

remove_leaf()

remove_filename()

basic_path basic_path( const string_type & str,
  name_check )
該特性被去除
basic_path basic_path( const string_type::value_type * s,
  name_check )
該特性被去除
basic_path native_file_string() file_string()
basic_path native_directory_string() directory_string()
basic_path default_name_check_writable() 該特性被去除
basic_path default_name_check( name_check ) 該特性被去除
basic_path default_name_check() 該特性被去除
basic_path canonize() 該特性被去除
basic_path normalize() 該特性被去除
operations.hpp is_regular( file_status f ) is_regular_file( file_status f )
operations.hpp symbolic_link_exists( const path & ph ) 該特性被去除
basic_directory_status filename() 該特性被去除,用 path().filename() 替代
basic_directory_status leaf() 該特性被去除,用 path().filename() 替代
basic_directory_status string() 該特性被去除,用 path().string() 替代

只使用窄字符路徑

對於不支持寬字符(wchar_t)或寬字符串(std::wstring)的編譯器或標準庫,系統可以自動檢測,並會引起本庫的編譯碼限於只使用 窄字符路徑(boost::filesystem::path)。用戶可以強加這一局限,只要定義宏 BOOST_FILESYSTEM_NARROW_ONLY 就可以了。這對於舊的編譯器或操作系統非常有用。

構建目標庫

如果你使用的是 Boost 構建系統,則目標庫將被自動構建。請見 入門Getting Started. 你也可以用在目錄 libs/filesystem/build 中提供的 Jamfile 進行手工構建,或者可以建立一個包含目標庫源文件的 IDE 項目或 make 文件。

目標庫源文件在目錄 libs/filesystem/src 中提供。這些源文件實現了支持 POSIX 或 Windows 兼容操作系統的庫;不提供支持其它操作系統的實現。注意,許多並不被認為是 POSIX 系統的操作系統,如傳統的大型機操作系統或嵌入式操作系統,只要支持 POSIX 兼容的文件系統,也可以使用 Filesystem 庫。

目標庫可以構建為靜態或動態(shared/dll)鏈接。這是由 BOOST_ALL_DYN_LINK 或 BOOST_FILESYSTEM_DYN_LINK 宏來控制的。對所用技術的說明請見 Separate Compilation 頁。

給 Cygwin 用戶的說明

本庫的實現代碼自動檢測當前平台,並據此編譯為 POSIX 或 Windows 實現。在目標庫編譯過程中的自動平台檢測可以通過定義 BOOST_POSIX_API 或 BOOST_WINDOWS_API 宏來改變。除了 Cygwin 以外,通常沒有理由定義這些宏,因為多數編譯器提供的軟件開發包只支持單一平台。

Cygwin 的工具包支持傳統的 Windows 使用,但也提供了一個模擬層和其它工具,把 Windows 弄得像 Linux (也就是 POSIX)一樣,提供了 Linux 的外觀和感覺。GCC 通常是這個環境下的編譯器選擇,它可以在 Cygwin 安裝過程中安裝。其它編譯器也可以使用 Cygwin 的 POSIX 模擬,至少在理論上是可以的。

這些使用 Cygwin POSIX 模擬層的願望需要在編譯用戶程序和 Boost.Filesystem 的目標庫時定義 BOOST_POSIX_API 宏。 

鳴謝

The Filesystem Library was designed and implemented by Beman Dawes. The original directory_iterator and filesystem_error classes were based on prior work from Dietmar Kuehl, as modified by Jan Langer. Thomas Witt was a particular help in later stages of initial development. Peter Dimov and Rob Stewart made many useful suggestions and comments over a long period of time. Howard Hinnant helped with internationalization issues.

Key design requirements and design realities were developed during extensive discussions on the Boost mailing list, followed by comments on the initial implementation. Numerous helpful comments were then received during the Formal Review.

Participants included Aaron Brashears, Alan Bellingham, Aleksey Gurtovoy, Alex Rosenberg, Alisdair Meredith, Andy Glew, Anthony Williams, Baptiste Lepilleur, Beman Dawes, Bill Kempf, Bill Seymour, Carl Daniel, Chris Little, Chuck Allison, Craig Henderson, Dan Nuffer, Dan'l Miller, Daniel Frey, Darin Adler, David Abrahams, David Held, Davlet Panech, Dietmar Kuehl, Douglas Gregor, Dylan Nicholson, Ed Brey, Eric Jensen, Eric Woodruff, Fedder Skovgaard, Gary Powell, Gennaro Prota, Geoff Leyland, George Heintzelman, Giovanni Bajo, Glen Knowles, Hillel Sims, Howard Hinnant, Jaap Suter, James Dennett, Jan Langer, Jani Kajala, Jason Stewart, Jeff Garland, Jens Maurer, Jesse Jones, Jim Hyslop, Joel de Guzman, Joel Young, John Levon, John Maddock, John Williston, Jonathan Caves, Jonathan Biggar, Jurko, Justus Schwartz, Keith Burton, Ken Hagen, Kostya Altukhov, Mark Rodgers, Martin Schuerch, Matt Austern, Matthias Troyer, Mattias Flodin, Michiel Salters, Mickael Pointier, Misha Bergal, Neal Becker, Noel Yap, Parksie, Patrick Hartling, Pavel Vozenilek, Pete Becker, Peter Dimov, Rainer Deyke, Rene Rivera, Rob Lievaart, Rob Stewart, Ron Garcia, Ross Smith, Sashan, Steve Robbins, Thomas Witt, Tom Harris, Toon Knapen, Victor Wagner, Vincent Finn, Vladimir Prus, and Yitzhak Sapir

A lengthy discussion on the C++ committee's library reflector illuminated the "illusion of portability" problem, particularly in postings by PJ Plauger and Pete Becker.

Walter Landry provided much help illuminating symbolic link use cases for version 1.31.0.

版本 1.34 (i18n) 的鳴謝

So many people have contributed comments and bug reports that it isn't any longer possible to acknowledge them individually. That said, Peter Dimov and Rob Stewart need to be specially thanked for their many constructive criticisms and suggestions. Terence Wilson and Chris Frey contributed timing programs which helped illuminate performance issues.

變更歷史

版本 1.37.0

版本 1.36.0 - August 14th, 2008

版本 1.35.0 - March 29th, 2008

版本 1.34.1 - July 24th, 2007

版本 1.34.0 - May 12th, 2007

版本 1.33.0 - August 11th, 2005

版本 1.32.0 - November 19th, 2004

版本 1.31.0 - January 26th, 2004

Version 1.30.0 - March 19th, 2003


Revised 28 October, 2008

Ac Copyright Beman Dawes, 2002-2005

Use, modification, and distribution are subject to the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt