![]() |
Filesystem 庫 |
| Boost Home Library Home Tutorial Reference FAQ |
本庫早期版本中的有些函數已經改名或不再使用。請見 不再使用的名稱和特性。
本庫的有些行為是通過引用 ISO/IEC 9945:2003, POSIX 來規定的。這些行為如何實現則並沒有規定。
[註:這為與操作系統相關的行為的實現制定了一個"類似"規則。大概這些實現通常都會調用 原生的操作系統API. --注完]
實現被鼓勵,但不要求,支持 POSIX 所定義的行為。實現應該對與 POSIX 定義的行為有所不同的行為給出文檔說明。實現如果由於操作系統和文件系統的局限,而不能支持精確的 POSIX 行為,則應盡量提供接近 POSIX 的合理行為。如果一個實現不能提供任何合理的行為,該實現應該以實現定義的方式報告一個錯誤。
[註:這類錯誤可能通過一個 #error 指示, 一個
static_assert, 一個basic_filesystem_error異常, 一個特定的返回值,或其它方式來報告。--注完]
特定的操作系統,如 OpenMVS, UNIX, 和 Windows 僅在示範或給出實現指導時提及。不提及其它操作系統是有意的。
在本參考手冊中給出的函數的 效果 和 後置條件 可能不適用於 競爭條件 的情形。這類診斷並不被要求。
如果可能存在競爭條件,使得程序在調用函數之前測試某個前提條件變得不可靠,則不指定這樣的 Requires. 反之,這些條件被指定為 Throws 條件。
[註:作為一個設計實踐,如果要求一個程序在調用函數之前檢查前提條件是不合理的,則這些 前提條件不會被規定。 -- 注完]
在本參考手冊中,使用了以下定義:
文件:一個對 象,可以寫入、讀出或兩者俱可。文件具有確定的屬性,包括類型。文件類型包括有:普通文件、符號鏈接和目錄。實現還可能支持其它文件類型。
文件系統:一 組文件和它們的屬性。
文件名:文 件的名字。其格式由 POSIX 文 件名Filename 基本定義所指定。
路徑:一組元 素序列,用以標識文件系統中的某個位置。這些元素是 root-name, root-directory, 以及各個連續的文件名。請見 路徑名語法。
路徑名:表 示一個路徑的一個字符串。
鏈接:一個目 錄項對象,它關聯某個文件的文件名。在某些文件系統中,多個目錄項可以關聯同一個文件名。
硬鏈接:到 一個已有文件的鏈接。有些文件系統支持同一個文件的多個硬鏈接。如果最後一個硬鏈接被刪除,則文件本身被刪除。
[註:硬鏈接可以被視為一個文件的所有權共享智能指針。-- 注完]
符號鏈接:一 種文件類型,在路徑名解析過程中使用,文件中保存的字符串被用於修改路徑名的解析。
[註:符號鏈接可以被視為一個文件的原始指針。如果被指向的文件不存在,則該符號鏈接被稱 為 "懸空" 的符號鏈接。-- 注完]
斜線符: 字符 '/', 也稱為斜線分隔符。
點符: 字符 '.', 也稱為句點。
競爭條件:當 多個線程、進程或計算機交錯訪問和修改文件系統中的同一個對像時發生的情形。
在本文中名為 Path, Path1,
或 Path2 的模板參數都應為類型 basic_path,
或是派生自 basic_path 一某個類,除非特別說明。
在本文中,有些函數模板具有名為 Path, Path1,
或 Path2 的模板參數。當以類型為 char*
或
std::string 的參數 s
來調用這些函數時,實現應將這個參數視作為 path(s). 當以類型為 wchar_t*
或 std::wstring 的參數 s
來調用這些函數時,實現應將這個參數視作為 wpath(s).
對於帶兩個參數的函數,實現不應支持將 Path1 和 Path2
作為不同類型來處理。
[註:這個 "do-the-right-thing" 規則允許用戶寫象
exists("foo")這樣的代碼,利用類basic_path的字符串轉換構造函數,而不需要寫又長又容易出錯的exists(path("foo")). 這對於編寫簡單、類似於腳本的程序尤其重要,這也正是本庫的一個主要應用。以不同類型的兩個參數來調用函數的情況非常罕見,很可能是代碼錯誤,所以這種情 形下的自動轉換是不被支持的。實現的技術並不特別規定。以
exists()為例,以下是一種可能的實現技術:template <class Path>
typename boost::enable_if<is_basic_path<Path>,bool>::type exists(const Path& p);
inline bool exists(const path& p) { return exists<path>(p); }
inline bool exists(const wpath& p) { return exists<wpath>(p); }對於C字符串或
std::basic_string參數,enable_if將會失敗,這樣就會通過適當的basic_path轉換構造函數自動轉換為basic_path對象。-- 注完]這 兩個重載沒有在正式文本中給出,是因為:
- 可 能會有更好的方法達到這一效果,如通過核心語言實現對 Concepts 的支持。
- 實 現可能會選用其它技術,以便用於那些不支持 enable_if 的舊編譯器。
- 清 楚說明這些重載會使得文本更長,更難以閱讀,而沒有增加任何好處。
- 對 於 char16_t 和 char32_t 可能需要更多的重載(或者規定它們不允許調用),每一個都要講清楚就更麻煩了。
本文中的函數的實現可以調用由操作系統系統提供的API. 如果調用這些操作系統API產生了錯誤,則實現應通過拋出 basic_filesystem_error
異常來報告錯誤,除非特別說明。
[註:這些異常及其拋出條件不會在本文的每一個 Throws 單元中說明。因為在文件系統操作中,硬件錯誤、網絡失敗、競爭條件和其它多種錯誤都會常常發生,用戶應該知道,除非特別說明,任何的文件系統操作,無論看 起來多麼沒有危險,都可能會拋出異常。-- 注完]
對
於那些常常用在錯誤不被視為異常的環境中的函數,都有其它重載,接受一個額外的參數 error_code&
ec.
這些函數重載不拋出異常。如果發生了錯誤,ec 將被設置為操作系統所報告的錯誤碼,否則 ec
被設為 0. 如果沒有類型
error_code&
ec 參數的重載是返回 void
的,則另一個重載(帶有類型
error_code&
ec 參數的)將返回一個
error_code,值為 ec.
<boost/filesystem>
概要namespace boost
{
namespace filesystem
{
template <class String, class Traits> class basic_path;
template<class String, class Traits>
void swap(basic_path<String, Traits> & lhs, basic_path<String, Traits> & rhs);
template<class String, class Traits> bool operator<(a a, b b);
template<class String, class Traits> bool operator==(a a, b b);
template<class String, class Traits> bool operator!=(a a, b b);
template<class String, class Traits> bool operator>(a a, b b);
template<class String, class Traits> bool operator<=(a a, b b);
template<class String, class Traits> bool operator>=(a a, b b);
template<class String, class Traits> bool operator/(a a, b b);
template<class Path>
basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type> &
operator<<(basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type>& os, const Path & ph);
template<class Path>
basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type> &
operator>>(basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type>& is, Path & ph);
struct path_traits;
struct wpath_traits;
typedef basic_path<std::string, path_traits> path;
typedef basic_path<std::wstring, wpath_traits> wpath;
template<class Path> struct is_basic_path;
template<class Path> struct slash { static const char value = '/'; };
template<class Path> struct dot { static const char value = '.'; };
template<class Path> struct colon { static const char value = ':'; };
class filesystem_error;
template <class Path> class basic_filesystem_error;
typedef basic_filesystem_error<path> filesystem_error;
typedef basic_filesystem_error<wpath> wfilesystem_error;
template <class Path> class basic_directory_entry;
typedef basic_directory_entry<path> directory_entry;
typedef basic_directory_entry<wpath> wdirectory_entry;
template <class Path> class basic_directory_iterator;
typedef basic_directory_iterator<path> directory_iterator;
typedef basic_directory_iterator<wpath> wdirectory_iterator;
template <class Path> class basic_recursive_directory_iterator;
typedef basic_recursive_directory_iterator<path> recursive_directory_iterator;
typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator;
enum file_type { status_unknown, file_not_found, regular_file, directory_file,
symlink_file, block_file, character_file, fifo_file, socket_file,
type_unknown
};
class file_status;
struct space_info // returned by space function
{
uintmax_t capacity;
uintmax_t free;
uintmax_t available;
};
// status functions
template <class Path> file_status status(const Path& p);
template <class Path> file_status status(const Path& p, error_code& ec);
template <class Path> file_status symlink_status(const Path& p);
template <class Path> file_status symlink_status(const Path& p, error_code& ec);
// predicate functions
bool status_known( file_status s );
bool exists( file_status s );
bool is_regular_file( file_status s );
bool is_directory( file_status s );
bool is_symlink( file_status s );
bool is_other( file_status s );
template <class Path> bool exists(const Path& p);
template <class Path> bool is_directory(const Path& p);
template <class Path> bool is_regular_file(const Path& p);
template <class Path> bool is_other(const Path& p);
template <class Path> bool is_symlink(const Path& p);
template <class Path> bool is_empty(const Path& p);
template <class Path1, class Path2>
bool equivalent(const Path1& p1, const Path2& p2);
// attribute functions
template <class Path> Path current_path();
template <class Path> void current_path(const Path& p);
template <class Path> const Path& initial_path();
template <class Path> uintmax_t file_size(const Path& p);
template <class Path> space_info space(const Path& p);
template <class Path> std::time_t last_write_time(const Path& p);
template <class Path>
void last_write_time(const Path& p, const std::time_t new_time);
// operations functions
template <class Path> bool create_directory(const Path& dp);
template <class Path1, class Path2>
void create_hard_link(const Path1& old_fp, const Path2& new_fp);
template <class Path1, class Path2>
error_code create_hard_link(const Path1& old_fp, const Path2& new_fp, error_code& ec);
template <class Path1, class Path2>
void create_symlink(const Path1& old_fp, const Path2& new_fp);
template <class Path1, class Path2>
error_code create_symlink(const Path1& old_fp, const Path2& new_fp, error_code& ec);
template <class Path> bool remove(const Path& p);
template <class Path1, class Path2>
void rename(const Path1& from_p, const Path2& to_p);
template <class Path1, class Path2>
void copy_file(const Path1& from_fp, const Path2& to_fp);
template <class Path> Path system_complete(const Path& p);
template <class Path> Path complete(const Path& p, const Path& base=initial_path<Path>());
// convenience functions
template <class Path> bool create_directories(const Path& p);
template <class Path> typename Path::string_type extension(const Path& p);
template <class Path> typename Path::string_type basename(const Path& p);
template <class Path>
Path change_extension(const Path& p, const typename Path::string_type& new_extension);
} // namespace filesystem
} // namespace boost
這一節定義了對表示路徑行為的 traits 類的要求,並且定義了兩個類,分別滿足對基於 string 和 wstring 的路徑的這些要求。還定義了幾個額外的 path traits 結構模板,以及這些模板的特化。
在本文中定義的類模板 basic_path
要求一些其它的類型、值和行為來完成對其語義的定義。
從作用上說,Traits 的行為就像它是一個帶有一個被初始化為 false 的私有成員 bool m_locked,以及一個已初始化的成員 std::locale m_locale 的類。
| 路徑行為 Traits 要求 | |
| 表 達式 | 要 求 |
Traits::external_string_type |
一個 typedef,它是 basic_string
的一個特化。其 value_type 為操作系統用於表示路徑名的字符類型。 |
Traits::internal_string_type |
一個 typedef,它是 basic_string
的一個特化。其 value_type 為程序用於表示路徑名的字符類型。要求它與 basic_path
的 String 模板參數具有相同類型。 |
Traits::to_external(
p, is ) |
is, 被 m_locale
codecvt facet 轉換為 external_string_type. |
Traits::to_internal(
p, xs ) |
xs, 被 m_locale
codecvt facet 轉換為 internal_string_type. |
Traits::imbue(loc) |
作用:如果 m_locked,
則拋出異常。否則 m_locked = true; m_locale = loc;返回:void拋出: basic_filesystem_error |
Traits::imbue(loc,
std::nothrow) |
作用:如果
(!m_locked) 則 m_locale = loc; bool temp(m_locked); m_locked =
true;返回:temp |
類型 is_basic_path 應該是一個 UnaryTypeTrait
(TR1, 4.1). 其主模板應直接或間接派生自
std::tr1::false_type. 類型 is_basic_path
應針對 path, wpath,
和任何用戶專有 basic_path 類型進行特化,而且這些特化都應直接或間接派生自 std::tr1::true_type.
結構模板 slash, dot,
和
colon
用於提供類型為 char 的值。如果某個用戶專有 basic_path
具有不可由 char 轉換而得的
value_type 類型,則模板 slash 和 dot
應被特化,以提供某種可轉換為
basic_path::value_type 的類型的值。
basic_path類模板 basic_path 提供了一個在C++程序中表示 路徑paths 的可移植機制,它使用可移植的通用路徑名語法。當不需要可移植性時,可以使用原生文件系統的特定
格式。類模板
basic_path
只關心路徑的詞法和語法方面。該路徑不要求在操作系統的文件系統中存在,也可能包含某些當前操作系統認為無效的名字。
[註:如果本庫的函數只能使用C++或C風格的字符串,那麼它們的可移植性只是幻想,因為 雖然函數調用的語法是可移植的,但函數所操作的字符串的語義卻不可移植。-- 注完]
namespace boost
{
namespace filesystem
{
template <class String, class Traits> class basic_path
{
public:
typedef basic_path<String, Traits> path_type;
typedef String string_type;
typedef typename String::value_type value_type;
typedef Traits traits_type;
typedef typename Traits::external_string_type external_string_type;
// constructors/destructor
basic_path();
basic_path(const basic_path& p);
basic_path(const string_type& s);
basic_path(const value_type* s);
template <class InputIterator>
basic_path(InputIterator first, InputIterator last);
~basic_path();
// assignments
basic_path& operator=(const basic_path& p);
basic_path& operator=(const string_type& s);
basic_path& operator=(const value_type* s);
template <class InputIterator>
basic_path& assign(InputIterator first, InputIterator last);
// modifiers
basic_path& operator/=(const basic_path& rhs);
basic_path& operator/=(const string_type& s);
basic_path& operator/=(const value_type* s);
template <class InputIterator>
basic_path& append(InputIterator first, InputIterator last);
void clear();
void swap( basic_path & rhs );
basic_path& remove_filename();
basic_path& replace_extension(const string_type & new_extension = "");
// observers
const string_type string() const;
const string_type file_string() const;
const string_type directory_string() const;
const external_string_type external_file_string() const;
const external_string_type external_directory_string() const;
string_type root_name() const;
string_type root_directory() const;
basic_path root_path() const;
basic_path relative_path() const;
basic_path parent_path() const;
string_type filename() const;
string_type stem() const;
string_type extension() const;
bool empty() const;
bool is_complete() const;
bool has_root_name() const;
bool has_root_directory() const;
bool has_root_path() const;
bool has_relative_path() const;
bool has_filename() const;
bool has_parent_path() const;
// iterators
class iterator;
typedef iterator const_iterator;
iterator begin() const;
iterator end() const;
};
} // namespace filesystem
} // namespace boost
一個 basic_path 對象可以保存空路徑。保存路徑的內部形式並不指定。
在本文中描述的訪問文件及其屬性的函數要將
一個 basic_path
對像解析為文件層次中的一個特定文件。路徑名被合適地轉換為操作系統所要求的字符串類型、格式和編碼,按 POSIX
Pathname
Resolution 機制進行解析。結果路徑名的編碼由 Traits::to_external
轉換函數決定。
[註:並不保證保存在
basic_path對像中的路徑對於特定的操作系統或文件系統是有效的。-- 注完]
本文中有些函數返回的 basic_path
對像部分或全部由得自操作系統的路徑名組成。這些路徑名被從由操作系統提供的真實格式和字符串類型進行合適的轉換。結果路徑的編碼由 Traits::to_internal
轉換函數決定。
那些返回 "const string_type" 或 "const
external_string_type" 的成員函數,允許被實現為分別返回 "const
string_type&" 或 "const
external_string_type&"。
[註:這允許實現避免不必要的複製。指定以常量值返回可以確保在轉換為以引用返回的實現時 不會破壞已有程序。-- 注完]
有兩種格式的字符串或字符序列參數來表示一個路徑:
[註:POSIX 格式是可移植格式的基礎,因為它已經是一個ISO標準了,它也是廣泛採用的URL格式,是類UNIX和 類Windows操作系統的原生格式或其子集,為廣大程序員所熟悉。
單靠使用可移植格式並不能保證可移植性;文件名也必須是可移植的。請見 文件名轉換。每個操作系統都有它自己的規則。使用 可移植格式並不能改變這些規則。 -- 注完]
[註:如果操作系統只支持POSIX 路徑名格式,則可移植格式和原生格式就是一樣的。
確 定用戶所提供的路徑作為原生格式,是一種常見的需要,並且確保了最大的可移植性,雖然這並不是嚴格需要的,除了在那些原生格式未被公認的系 統上。
使 用硬編碼原生格式的程序很可能是不可移植的。-- end note]
所
有 basic_path
的描述路徑的字符串或字符序列參數都接受可移植路徑名格式,也接受由原生格式轉義序列前綴"//:"顯式標識的原生格式。
[註:
"//:"被選擇 作為轉義序列,是因為在POSIX中"//"是由實現 定義的,":"則是不允許用於Windows 文件,而且在任何系統中如果想表示以":"開頭的文件名,可以使用單個"/"。以上因素一起消除了這個轉義序列與某個真實文件名發生衝突的可能。-- 注完]
如 果在文字上可以區分開,實現最好可以直接接受原生的路徑名格式。每個實現應該在文檔中寫明是否可以直接接受原生路徑名格式。
[例如:
-- OpenVMS:
"SYS1::DISK1:[JANE.TYLER.HARRY]" 被視為帶有系統名、驅動器名和三個目錄文件名的原生路徑名,而不是某個文件名的可移植路徑名。-- Windows:
"c:\\jane\\tyler\\harry"被視為帶有驅動器名、根目錄和三個文件名的原生路徑名,而不是某個文件名的可移植路徑名。-- 反例1: 某個操作系統允許在文件名中使用"/",它使用"."作為目錄分隔符。區分可移植格式和原生格式的字符串或字符序列是不可能的,如果沒有其它可區分的語 法。所以實現不接受原生格式的路徑名,除非指定一個原生參數。
-- 反例2: 某個操作系統允許在文件名中使用"/",它使用一些不常見的字符作為目錄分隔符。這時實現不能接受不帶有額外的原生參數的原生格式路徑名,原生參數必須被 用於在文件名中含有"/"的原生格式參數。
-- 舉例完]
[註:鴨 子規則duck-rule ("如果某個東西看起來像鴨子,走起來像鴨子,叫進來象鴨子,那麼它就是一隻鴨子")消除了源自程序員錯誤和支持要求的格式混亂。-- 注完]
如果可以同時接受可移植格式和原生格式,則實現應該在文檔中說明哪些字符或字符序列被用作區分可移植格式和原生格式。
[註:Windows 實現被鼓勵將":"和"\"定義為區分原生格式和可移植格式的字符。--注完]
可移植路徑名格式的語法如下:
pathname:
root-nameopt root-directoryopt relative-pathoptroot-name:
implementation-definedroot-directory:
slash
root-directory slash
implementation-definedrelative-path:
filename
relative-path slash
relative-path slash filenamefilename:
name
dot
dot dotslash:
slash<Path>::valuedot:
dot<Path>::value
該語法是參照 POSIX 的 Filename, Pathname 和 Pathname Resolution 定義的。該語法與 POSIX 間的任何衝突都不是故意的。本技術報告遵守 POSIX.
以 上表達形式取自於 POSIX, 後者在多次使用該方式引向 C 標準。
[註:Windows 實現被鼓勵將"//name" 定義為可允許的 root-name. POSIX 允許但不要求相關實現也這樣做。Windows 實現被鼓勵定義另一個 root-directory 元素 root_directory name. 它只適用於 root-name 的 "//name" 格式。
Windows 實現被鼓勵在 name 前加一個":"作為原生格式的 root-name, 將"\"作為與"/"等價的格式元素。-- 注完]
在將文件轉換為原生操作系統格式時,建議但不要求實現將無效字符或字符序列轉換為有效的字符或字符序列。這些轉換是由實現定義的。
[註:文件轉換給了程序和文件名更大的可移植能力。
建議實現基於已有標準或實踐之上進行轉換。相關例子包括URL的轉義語法,即在百分號(
'%') 後跟兩位十六進制數字來表示字符值。在 OpenVMS, 不允許在文件名中出現百分號,所以使用美元符('$') 後跟兩位十六進制數字,還有將小寫字母轉為大寫。-- 注完]Windows 平台上的Boost實現目前不進行無效字符映射。來自LWG的未決反饋是,Boost可能決定用 % hex hex 作為轉義序列。如果是這樣,是否會有標準化的建議?
名為 String 的模板參數的實參應該是一個含有與類模板 basic_string
相同名字、類型、值和語義的成員的類。
名為 Traits 的模板參數的實參應該是一個滿足
路徑行為 Traits 要求
表中給出的要求的類。
名為 InputIterator
的模板參數的實參應該滿足輸入迭代器的要求(C++標準,24.1.1,Input iterators
[lib.input.iterators]),並且應該具有可以轉換為
basic_path::value_type 的值類型。
有些帶有 InputIterator
模板參數的函數模板還有其它非模板的重載形式。如果 InputIterator 的類型不是 path_format_t,
則實現應該只選擇函數模板的重載。
[註:"do-the-right-thing" 規則確保用戶期望的重載會被選中。實現的技術並未規定 - 具體實現可以使用 enable_if 或者其它技術來實現這一效果。-- 注完]
basic_path
構造函數basic_path();
後置條件:
empty().
basic_path(const string_type& s);
basic_path(const value_type * s);
template <class InputIterator>
basic_path(InputIterator s, InputIterator last);
備註: 字符串
s及字符序列 [first,last) 的格式在 路徑名格式 中說明。作用: 保存字符串
s或字符序列 [first,last) 中的路徑元素。
basic_path
賦值basic_path& operator=(const string_type& s);
basic_path& operator=(const value_type* s);
template <class InputIterator>
basic_path& assign(InputIterator first, InputIterator last);
備註: 字符串
s及字符序列 [first,last) 的格式在 路徑名格式 中說明。作用: 保存字符串
s或字符序列 [first,last) 中的路徑元素。返回:
*this
basic_path
修改器basic_path& operator/=(const basic_path& rhs);
作用: 將保存在
rhs中的路徑增加到保存的路徑中。返回:
*this
basic_path& operator/=(const string_type& s);
basic_path& operator/=(const value_type* s);
template <class InputIterator>
basic_path& append(InputIterator first, InputIterator last);
備註: 字符串
s及字符序列 [first,last) 的格式在 路徑名格式 中說明。作用: 將字符串
s或字符序列 [first,last) 中的路徑元素增加到保存的路徑中。返回:
*this
void clear();
後置條件:
this->empty()為真。
void swap( basic_path & rhs );
作用: 交換兩個路徑的內容。
拋出: 無。
後置條件:
this->string()包含與rhs.string()相同的字符序列,rhs.string()則包含與this->string()相同的字符序列。複雜度: 常量時間。
basic_path& remove_filename();
作用: 如果
has_parent_path()則從保存的路徑中刪除最後的 filename. 如果路徑中剩下的最後的一個或多個"/"不是表示根 目錄,就刪除它們。返回:
*this[注: 該函數對於高效實現
basic_directory_iterator是必須的。它被設為公有的,可用於其它用途。-- 注完]
basic_path& replace_extension( const string_type & new_extension = "" );
後置條件:
extension() == replacement, 其中replacement為new_extension如果new_extension.empty() || new_extension[0] =='.',否則replacement為'.'後跟new_extension。返回:
*this
basic_path
觀察器由 分解函數所返回的值的示例請見 路徑分解表。
const string_type string() const;
返回: 所保存的路徑,按照 路徑名語法 規則進行格式化。
const string_type file_string() const;
返回: 所保存的路徑,按照操作系統關於常規文件路徑名的規則進行格式化,帶 文件名轉換。
[注: 對於某些操作系統,包括 POSIX 和 Windows, 常規文件和目錄的路徑名的原生格式是相同的,所以
file_string()和directory_string()返回相同的字符串。但是在 OpenMVS 上,表達式path("/cats/jane").file_string()返回字符串"[CATS]JANE"而path("/cats/jane").directory_string()則返回字符串"[CATS.JANE]". -- 注完]
const string_type directory_string() const;
返回: 所保存的路徑,按照操作系統關於目錄路徑名的規則進行格式化,帶 文件名轉換。
const external_string_type external_file_string() const;
返回: 所保存的路徑,按照操作系統關於常規文件路徑名的規則進行格式化,帶 文件名轉換,並由
Traits::to_external轉換函數進行編碼。
const external_string_type external_directory_string() const;
返回: 所保存的路徑,按照操作系統關於目錄路徑名的規則進行格式化,帶 文件名轉換,並由
Traits::to_external轉換函數進行編碼。
string_type root_name() const;
返回: root-name, 如果所保存的路徑中包含 root-name, 否則返回
string_type().
string_type root_directory() const;
返回: root-directory, 如果所保存的路徑中包含 root-directory, 否則返回
string_type().如果 root-directory 由"/"加 name 組成,則"/"被排除在返回字符串之外。
basic_path root_path() const;
返回:
root_name() / root_directory()
basic_path relative_path() const;
返回: 從被保存的路徑組成的
basic_path, 如果有則返回 root-path 加上第一個 filename。 否則返回空的basic_path.
string_type filename() const;
返回:
empty() ? string_type() : *--end()
basic_path parent_path() const;
返回:
(string().empty() || begin() == --end()) ? path_type("") : br, 其中br是這樣構成的:以一個空的basic_path開始,對begin(),--end()間的每個元素相繼應用operator/=。
string_type stem(const Path & p) const;
返回: 如果
p.filename()包含一個'.',則返回p.filename()中從開頭起至最後一個'.'的子串(不包含'.')。否則,返回p.filename()。
string_type extension(const Path & p) const;
返回: 如果
p.filename()包含一個'.',則返回p.filename()中從最右一個'.'起至末尾的子串。否則,返回一個空串。[注: 返回值中是包含'.'的,所以可以區分 無擴展名和空擴展名。
具體實現可以允許但不要求為那些在擴展名上增加其它元素,如數據流或分區數據集名,的文件系統定義額外的行為。 -- 注完]
bool empty() const;
返回:
string().empty().
bool is_complete() const;
返 回:
true, 如果 root_path() 的元素唯一地標識了一個目錄,否則返回false.
bool has_root_path() const;
返回:
!root_path().empty()
bool has_root_name() const;
返回:
!root_name().empty()
bool has_root_directory() const;
返回:
!root_directory().empty()
bool has_relative_path() const;
返回:
!relative_path().empty()
bool has_leaf() const;
返回:
!leaf().empty()
bool has_branch_path() const;
返回:
!branch_path().empty()
basic_path
迭代器 basic_path::iterator
是一個常量迭代器,它滿足雙向迭代器(C++ 標準, 24.1.4 Bidirectional iterators
[lib.bidirectional.iterators])的所有要求。它的 value_type
為
string_type.
對一個 basic_path 對象的任何非常性成員函數的調用將
使得引向該對像元素的所有迭代器均失效。
前向遍歷的順序如下:
後向遍歷的順序與前向遍歷相反。
iterator begin() const;
返回: 一個指向上述遍歷列表中第一個有效元素的迭代器。如果沒有這樣的元素,返回結束迭代器。
iterator end() const;
返回: 結束迭代器。
template<class String, class Traits>
void swap( basic_path<String, Traits> & lhs, basic_path<String, Traits> & rhs )
作用:
lhs.swap( rhs )
basic_path
有七個非成員操作符(/, ==,
!=,
<,
>,
<=,
>=),
每個操作符有五個重載。為簡單起見,以表格形式給出規格說明。得到的35個函數簽名中的每一個都是一個模板,其模板參數列表為 template<class
String, class Traits>. 這些參數的格式在
路徑名格式 中描述。
|
參數類型重載 |
basic_path<String, Traits>& a,
basic_path<String, Traits>& b |
const
typename basic_path<String, Traits>::string_type&
a, basic_path<String, Traits>& b |
const
typename basic_path<String,
Traits>::string_type::value_type* a, basic_path<String,
Traits>& b |
const
basic_path<String, Traits>& a, typename
basic_path<String, Traits>::string_type& b |
const
basic_path<String, Traits>& a, typename
basic_path<String, Traits>::string_type::value_type* b |
在
basic_path
非成員操作符 表中,a 和 b 為
參數類型重載 表中給出的類型。如果 a 或 b 的類型為 const
basic_path<String, Traits>&, 則 a' 或 b' 分別為 a 或 b. 否則 a' 或 b' 分別表示從 a 或
b 構造的有名或無名的
basic_path<String,
Traits> 臨時對象。
| basic_path 非成員操作符 | ||
| 表 達式 | 返 回類型 | 語 義 |
a / b |
basic_path<String,
Traits> |
basic_path<String, Traits> tmp(a);b'; |
a < b |
bool |
return
lexicographical_compare(a'.begin(),
a'.end(),
b'.begin(),
b'.end()); |
a == b |
bool |
return !(a' < b')
&& !(b' < a'); |
a != b |
bool |
return !(a' == b'); |
a > b |
bool |
return b' < a'; |
a <= b |
bool |
return !(b' < a'); |
a >= b |
bool |
return !(a' < b'); |
等 同性由 basic_path 的非成員
operator==判定,它只考慮兩個路徑的字面表示。路徑 "abc" 和 "ABC" 是不等同的。等 價性則由 equivalent() 非成員函數來判定,它根據兩個路徑是否 解析resolve 為同一個文件系統實體來判定。路徑 "abc" 和 "ABC" 可能是也可能不是被解析為同一個文件,這取決於文件系統。
想 要判斷兩個路徑是否"相同"的程序員必須決定這裡所說的"相同"是指"相同的表示法"還是"解析為同一個文件",並據此選擇適當的函數。 -- 注完]
basic_path 插入器和提取器template<class Path>
basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type>&
operator>>(basic_istream< typename Path::string_type::value_type, typename Path::string_type::traits_type>& is,
Path& ph );
作用:
typename Path::string_type str;
is >> str;
ph = str;返回:
is
template<class Path>
basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type>&
operator<<(basic_ostream< typename Path::string_type::value_type, typename Path::string_type::traits_type>& os,
const Path& ph );
作用:
os << ph.string()返回:
os
basic_filesystem_errornamespace boost
{
namespace filesystem
{
template <class Path> class basic_filesystem_error : public system_error
{
public:
typedef Path path_type;
explicit basic_filesystem_error(const std::string& what_arg, error_code ec);
basic_filesystem_error(const std::string& what_arg, const path_type& p1, error_code ec);
basic_filesystem_error(const std::string& what_arg, const path_type& p1, const path_type& p2, error_code ec);
const path_type& path1() const;
const path_type& path2() const;
const char * what() const;
};
} // namespace filesystem
} // namespace boost
類模板 basic_filesystem_error
定義了一個被拋出的異常對像類型,它用於報告由本文中所列函數產生的文件系統錯誤。
basic_filesystem_error 構造函數explicit basic_filesystem_error(const std::string& what_arg, error_code ec);
後置條件:
表達式 值 runtime_error::what()what_arg.c_str()code()ecpath1().empty()truepath2().empty()true
basic_filesystem_error(const std::string& what_arg, const path_type& p1, error_code ec);
後置條件:
表達式 值 runtime_error::what()what_arg.c_str()code()ecpath1()一個指向所保存的 p1 拷貝的引用path2().empty()true
basic_filesystem_error(const std::string& what_arg, const path_type& p1, const path_type& p2, error_code ec);
後置條件:
表達式 值 runtime_error::what()what_arg.c_str()code()ecpath1()一個指向所保存的 p1 拷貝的引用path2()一個指向所保存的 p2 拷貝的引用
basic_filesystem_error
觀察器const path_type& path1() const;
返回: 指向由構造函數所保存的
p1拷貝的引用,或者如果沒有這樣的拷貝則返回空路徑。
const path_type& path2() const;
返回: 指向由構造函數所保存的
p2拷貝的引用,或者如果沒有這樣的拷貝則返回空路徑。
const char * what() const;
返回: 一個字符串,包含
runtime_error::what()及以code()作為第一參數調用system_message()所得的結果。精確的格式未指定。實現應該提供一個特化的
template<> const char * basic_filesystem_error<path>::what() const返回一個字符串,其中包含runtime_error::what(),以code()作為第一參數調用system_message()所得的結果,並且如果非空,則還有path1().file_string()和path2.file_string(). 精確的格式未指定。實現和用戶都被允許提供
what成員函數的其它特化。
basic_directory_entrynamespace boost
{
namespace filesystem
{
template <class Path> class basic_directory_entry
{
public:
typedef Path path_type;
typedef typename Path::string_type string_type;
// constructors
basic_directory_entry();
explicit basic_directory_entry(const path_type& p,
file_status st=file_status(), file_status symlink_st=file_status());
// modifiers
void assign(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());
void replace_filename(const string_type& s, file_status st=file_status(), file_status symlink_st=file_status());
// observers
const Path& path() const;
operator const Path&() const;
file_status status() const;
file_status status(error_code& ec) const;
file_status symlink_status() const;
file_status symlink_status(error_code& ec) const;
// comparisons
bool operator<(const basic_directory_entry<Path>& rhs);
bool operator==(const basic_directory_entry<Path>& rhs);
bool operator!=(const basic_directory_entry<Path>& rhs);
bool operator>(const basic_directory_entry<Path>& rhs);
bool operator<=(const basic_directory_entry<Path>& rhs);
bool operator>=(const basic_directory_entry<Path>& rhs);
private:
path_type m_path; // for exposition only
mutable file_status m_status; // for exposition only; stat()-like
mutable file_status m_symlink_status; // for exposition only; lstat()-like
};
} // namespace filesystem
} // namespace boost
basic_directory_entry 對像保存了一個 basic_path
對象,一個用於非符號鏈接狀態的 file_status
對象,以及一個用於符號鏈接狀態的
file_status 對象。file_status
對像擔當值緩存的角色。
[注: 因為一個路徑名的
status()可能是一個非常昂貴的操作,有些操作系統以目錄迭代副產品的方式提供狀態信息。緩存這些狀態信息可以顯著地節約時間。在有競爭條件的情況下,緩存與不緩存 的結果可能會有所不同。-- 注完]對 一個有15,047項的目錄進行迭代,冷啟動狀態下以非緩存方式查詢狀態耗費6秒鐘,而採用緩存方式查詢狀態則只要1秒鐘。測試環境為:Windows XP, 3.0 GHz 處理器,帶一個較快的硬盤。在 Linux 和 BSD-系 Unix 上進行目錄迭代的狀態查詢,也有類似的加速。
basic_directory_entry
構造函數basic_directory_entry();
後置條件:
表達式 值 path().empty()truestatus()file_status()symlink_status()file_status()
explicit basic_directory_entry(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());
後置條件:
表達式 值 path()pstatus()stsymlink_status()symlink_st
basic_directory_entry
修改器void assign(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());
後置條件:
表達式 值 path()pstatus()stsymlink_status()symlink_st
void replace_leaf(const string_type& s, file_status st=file_status(), file_status symlink_st=file_status());
後置條件:
表達式 值 path()path().branch() / sstatus()stsymlink_status()symlink_st
basic_directory_entry
觀察器const Path& path() const;
operator const Path&() const;
返回:
m_path
file_status status() const;
作 用: 就像:
if ( !status_known( m_status ) )
{
if ( status_known(m_symlink_status) && !is_symlink(m_symlink_status) )
{ m_status = m_symlink_status; }
else { m_status = status(m_path); }
}拋 出: 參見
status函數。返 回:
m_status
file_status status(error_code& ec) const;
作 用: 就像:
if ( !status_known( m_status ) )
{
if ( status_known(m_symlink_status) && !is_symlink(m_symlink_status) )
{ m_status = m_symlink_status; }
else { m_status = status(m_path, ec); }
}
else ec = 0;返 回:
m_status
file_status symlink_status() const;
作 用: 就旬:
if ( !status_known( m_symlink_status ) )
{
m_symlink_status = symlink_status(m_path);
}拋 出: 參見
symlink_status函數。返 回:
m_symlink_status
file_status symlink_status(error_code& ec) const;
作 用: 就像:
if ( !status_known( m_symlink_status ) )
{
m_symlink_status = symlink_status(m_path, ec);
}
else ec = 0;返 回:
m_symlink_status
basic_directory_iteratornamespace boost
{
namespace filesystem
{
template <class Path>
class basic_directory_iterator :
public iterator<input_iterator_tag, basic_directory_entry<Path> >
{
public:
typedef Path path_type;
// constructors
basic_directory_iterator();
explicit basic_directory_iterator(const Path& dp);
basic_directory_iterator(const Path& dp, error_code& ec);
basic_directory_iterator(const basic_directory_iterator& bdi);
basic_directory_iterator& operator=(const basic_directory_iterator& bdi);
~basic_directory_iterator();
// other members as required by
// C++ Std, 24.1.1 Input iterators [lib.input.iterators]
};
} // namespace filesystem
} // namespace boost
basic_directory_iterator
符合輸入迭代器的要求(C++ 標準, 24.1.1, Input iterators [lib.input.iterators])。
basic_directory_iterator
從其構造的目錄中持續讀入元素,類似於調用 POSIX
readdir_r().
當一個 basic_directory_iterator 被構造後,每一次調用 operator++,
它讀入並保存一個 basic_directory_entry<Path>
值及其可能帶有的相關狀態值。operator++ 不保持等同性,即:i
== j 並不意味著
++i == ++j.
[注: 不保持等同性的後果是,目錄迭代器只能被用於單次遍歷的算法。-- 注完]
如果到達目錄元素的末尾,迭代器將變為等同於 end 迭代器值。不帶參數的構造函數 basic_directory_iterator()
總是構造一個 end 迭代器對象,它是唯一一個用於結束條件的合法迭代器。一個 end 迭代器的
operator* 結果是未定義的。對於其它迭代器值,則返回一個 const
basic_directory_entry<Path>&. 一個 end
迭代器的
operator-> 結果也是未定義的。對於其它迭代器,則返回一個 const
basic_directory_entry<Path>*.
兩個 end 迭代器永遠都是相等的。一個 end 迭代器則不會等於一個非-end迭代器。
以上措詞基於標準庫的 istream_iterator 措詞。註釋被縮短並移至註解。
對一個
basic_directory_iterator 進行提領所得的
basic_directory_entry 對象,調用其 path()
成員,將得到一個 basic_path 對象的引用,該對像由構造該迭代器的目錄參數,通過
operator/= 加上目錄項文件名所組成。
[示例: 該程序接受一個可選的命令行參數,如果該參數為目錄路徑名,則對該目錄的內容進行遍歷。對於每個目錄項,輸出名字,如果某項為常 規文件則輸出文件的大小。
#include <iostream>
#include <filesystem>
using std::tr2::sys;
using std::cout;
int main(int argc, char* argv[])
{
std::string p(argc <= 1 ? "." : argv[1]);
if (is_directory(p))
{
for (directory_iterator itr(p); itr!=directory_iterator(); ++itr)
{
cout << itr->path().leaf() << ' '; // 只顯示文件名
if (is_regular(itr->status())) cout << " [" << file_size(itr->path()) << ']';
cout << '\n';
}
}
else cout << (exists(p) : "Found: " : "Not found: ") << p << '\n';
return 0;
}-- 示例完]
目錄的遍歷不會產生當前目錄(dot)和父目錄(dot dot) 的目錄項。
一個 basic_directory_iterator&
nbsp;持續遞增及提領所得到的目錄項的順序未指定。
[注: 執行目錄遍歷的程序可能想要測試從目錄迭代器提領所得的路徑是否真的存在。它可能是一個指向某個並不存在的文件的符號鏈接。對目錄樹進行遞歸遍歷並進行刪 除或改名操作的程序則可能希望避免進入符號鏈接。
如果在一個目錄的
basic_directory_iterator構造完成後,才在目錄中刪除或加入一個文件,則後續的迭代器遞增過程中是否會得到指向被刪或被加入項的迭代器,是未指定的。參見 POSIXreaddir_r(). --注完]
basic_directory_iterator
構造函數basic_directory_iterator();
作用: 構造 end 迭代器。
explicit basic_directory_iterator(const
Path& dp);
作用: 構造一個迭代器,表示由
dp所解析得到的目錄中的第一項,否則為 end 迭代器。[注: 要遍歷當前目錄,要寫
directory_iterator(".")而不是directory_iterator(""). -- 注完]
basic_directory_iterator(const Path& dp, error_code& ec );
作用: 構造一個迭代器,表示由
dp所解析得到的目錄中的第一項,否則為 end 迭代器。如果在得到結果時發生錯誤,則所得迭代器為 end 迭代器且ec被設置為操作系統所報告的錯誤代碼,否則為 0.
basic_recursive_directory_iteratornamespace boost
{
namespace filesystem
{
template <class Path>
class basic_recursive_directory_iterator :
public iterator<input_iterator_tag, basic_directory_entry<Path> >
{
public:
typedef Path path_type;
// constructors
basic_recursive_directory_iterator();
explicit basic_recursive_directory_iterator(const Path& dp);
basic_recursive_directory_iterator(const basic_recursive_directory_iterator& brdi);
basic_recursive_directory_iterator& operator=(const basic_recursive_directory_iterator& brdi);
~basic_recursive_directory_iterator();
// observers
int level() const;
// modifiers
void pop();
void no_push();
// other members as required by
// C++ Std, 24.1.1 Input iterators [lib.input.iterators]
private:
int m_level; // for exposition only
};
} // namespace filesystem
} // namespace boost
basic_recursive_directory_iterator
的行為與 basic_directory_iterator 相同,除了特別說明。
m_level 設為 0;it->is_directory()
為 true 且 no_push() 沒有緊接著最後一個遞增操作(或構造時)調用,則 m_level
被遞增,並進入該目錄且遞歸遍歷其內容。pop() 被調用時,m_level
被遞減,且後續將對父目錄進行遍歷,直至到達構造函數的參數所指定的目錄。level() 返回 m_level.level(), pop(),
和 no_push() 都要求該迭代器不是 end 迭代器。[注:
no_push()的一個用法是防止遞歸進入符號鏈接的目錄。為防止某些操作系統上的循環訪問,這是必須的。--注完]
namespace boost
{
namespace filesystem
{
class file_status
{
public:
explicit file_status( file_type v = status_unknown );
file_type type() const;
void type( file_type v );
};
} // namespace filesystem
} // namespace boost
file_status
對像保存了關於一個文件的狀態的信息。所保存的信息的內部形式未指定。
[注: 未來該類可能會被擴展,以保存更多的信息。--注完]
explicit file_status( file_type v = status_unknown );
作用: 保存
v.
file_type type() const;
返回: 所保存的
file_type.
void type( file_type v );
作用: 保存
v, 替換原先保存的值。
template <class Path> file_status status(const Path& p, error_code& ec);
template <class Path> file_status symlink_status(const Path& p, error_code& ec);
返回:
對於status,確定p的屬性就像 POSIXstat(), 而對於symlink_status確定的屬性則像 POSIXlstat().[注: 對於符號鏈接,
stat()會用符號鏈接的內容繼續進行路徑名解析,而lstat()則不會。-- 注完]如果在屬性確定過程中,操作系統報告了錯誤,則:
- 如果錯誤說明
p不能被解析,像 POSIX 的錯誤代碼 ENOENT 或 ENOTDIR 那樣,則設置 ec 為 0 並返回file_status(not_found_flag).否則:
- 否則,設置 ec 為操作系統報告的錯誤代碼並返回
file_status(status_unknown).
- 如果屬性顯示是一個常規文件,如 POSIX S_ISREG(), 則返回
file_status(regular_file).- 否則如果屬性顯示是一個目錄,如 POSIX S_ISDIR(), 則返回
file_status(directory_file).- 否則如果屬性顯示是一個符號鏈接,如 POSIX S_ISLNK(), 則返回
file_status(symlink_file). [注: 只能用於symlink_status. -- 注完]- 否則如果屬性顯示是一個塊設備文件,如 POSIX S_ISBLK(), 則返回
file_status(block_file).- 否則如果屬性顯示是一個字符設備文件,如 POSIX S_ISCHR(), 則返回
file_status(character_file).- 否則如果屬性顯示是一個 fifo 或管道文件,如 POSIX S_ISFIFO(), 則返回
file_status(fifo_file).- 否則如果屬性顯示是一個 socket, 如 POSIX S_ISSOCK(), 則返回
file_status(socket_file).- 否則返回
file_status(type_unknown).[注:
directory_file表示在這個文件上可以使用basic_directory_iterator,而regular_file則表示可以使用適當的<fstream>操作,假如沒有硬件、權限、訪問和競爭條件的錯誤。對於regular_file,反之則不一定為真;不是regular_file並不一定就表示<fstream>操作不能用於目錄。-- 注完]
template <class Path> file_status status(const Path& p);
作用:
system_error_code ec;
file_status stat(status(p, ec));拋出:
basic_filesystem_error<Path>如果ec != 0返回:
stat
template <class Path> file_status symlink_status(const Path& p);
作用:
system_error_code ec;
file_status stat(symlink_status(p, ec));拋出:
basic_filesystem_error<Path>如果ec != 0返回:
stat
bool status_known(file_status s);
返回:
s.type() != status_unknown
bool exists(file_status s);
返回:
status_known(s) && s.type() != file_not_found
template <class Path> bool exists(const Path& p);
返回:
exists( status(p) )
bool is_regular(file_status s);
返回:
s.type() == regular_file
template <class Path> bool is_regular(const Path& p);
返回:
is_regular( status(p) )
bool is_directory(file_status s);
返回:
s.type() == directory_file
template <class Path> bool is_directory(const Path& p);
返回:
is_directory( status(p) )
bool is_symlink(file_status s);
返回:
s.type() == symlink_file
template <class Path> bool is_symlink(const Path& p);
返回:
is_symlink( symlink_status(p) )
bool is_other(file_status s);
返回:
return exists(s) && !is_regular(s) && !is_directory(s) && !is_symlink(s)[注:
is_other()的規格保持不變,即使以後會加入is_xxx()函數。-- 注完]
template <class Path> bool is_other(const Path& p);
返回:
is_other( status(p) )
template <class Path> bool is_empty(const Path& p);
作用: 確定
file_status s, 如status(p).拋出:
basic_filesystem_error<Path>如果!exist(s) || is_other(s).返回:
is_directory(s)
? basic_directory_iterator<Path>(p) == basic_directory_iterator<Path>()
: file_size(p) == 0;
template <class Path1, class Path2> bool equivalent(const Path1& p1, const Path2& p2);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用: 確定
file_status s1和s2, 就如status(p1)和status(p2).拋出:
basic_filesystem_error<Path1>如 果(!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2)).返回:
true, 如果sf1 == sf2且p1和p2解析為同一個文件系統實體,否則返回false.兩個路徑被認為是解析為同一個文件系統實體,如果這兩個候選實體位於同一設備的同一位置。這就像 POSIX
stat結構的值所確定的那樣,對兩個路徑調用stat()所得到的值,具有相等的st_dev值和相等的st_ino值。[注: POSIX 要求"st_dev 在一個LAN中必須是唯一的"。舊的 POSIX 實現可能還會檢查
st_size和st_mtime值是否相等。Windows 實現可能用GetFileInformationByHandle()代替stat(), 並認為"同一文件"是指dwVolumeSerialNumber,nFileIndexHigh,nFileIndexLow,nFileSizeHigh,nFileSizeLow,ftLastWriteTime.dwLowDateTime, 和ftLastWriteTime.dwHighDateTime值的相等。-- 注完]
[注: 可提供的屬性函數數量是嚴格受限的,因為只有少量文件系統屬性是可移植的。即使提供了這些函數,在某些文件系統上也不可能實現。--注 完]
template <class Path> const Path& initial_path();
返回: 進入
main()時的current_path().[注: 該語義將一個危險的全局變量變為一個安全的全局常量。--注完]
[注: 完整的實現需要運行期庫的支持。不能提供運行期庫支持的實現被建議保存第一次調用
initial_path()時所得的current_path()值, 並在後續調用時返回該值。使用initial_path()的程序建議在進入main()後立即調用它,這樣在這些實現中才可以正確工作。-- 注完]
template <class Path> Path current_path();
返回: 當前路徑,如 POSIX
getcwd().後置條件:
current_path().is_complete()[注: 許多操作系統返回的當前路徑都是一個危險的全局變量。它可能會被某個第三方庫或系統庫的函數所修改,或者被其它線程修改。雖然危險,但是該函數在處理其它 庫函數時非常有用。作為一個安全的選擇,請見
initial_path(). 選擇current_path()這個名字,是為了強調返回的是一個完整的路徑,而不是單個目錄名。-- 注完]
template <class Path> void current_path(const Path& p);
後置條件: equivalent( p, current_path() );
template <class Path> uintmax_t file_size(const Path& p);
返回: 由
p所解析得到的文件的字節大小,類似於由 POSIXstat()所得到的 POSIXstat結構的成員st_size中所確定的。
template <class Path> space_info space(const Path& p);
返 回: 一個
space_info對象。該space_info對象的值按以下方法確定,用 POSIXstatvfs()得到一個 POSIX 構造statvfs, 然後以用其f_frsize成員與f_blocks,f_bfree, 和f_bavail成員相乘,將結果分別賦值給capacity,free, 和available成員。無法確定值的成員將被設為 -1.
template <class Path> std::time_t last_write_time(const Path& p);
返回:
p的最後修改時間,即通過 POSIXstat()獲得的 POSIXstat結構的成員st_mtime的值。
template <class Path> void last_write_time(const Path& p, const std::time_t new_time);
作用: 將
p所解析得到的文件的最後修改時間設置為new_time, 就像 POSIXstat()後跟 POSIXutime().[注: 後置條件
last_write_time(p) == new_time未被指定,因為對於多數文件系統,由於時間機制的粒度較粗而未能保證該條件。-- 注完]
template <class Path> bool create_directory(const Path& dp);
作用: 嘗試創建一個由
dp解析得到的目錄,如 POSIXmkdir(), 以 S_IRWXU|S_IRWXG|S_IRWXO 為第二參數。拋出:
basic_filesystem_error<Path>如果上述作用因除目錄已存在以外的原因而失敗。返回: True 如果創建了新目錄,否則返回 false.
後置條件:
is_directory(dp)
template <class Path1, class Path2>
error_code create_hard_link(const Path1& to_p, const Path2& from_p, error_code& ec);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用: 建立後置條件,如 POSIX
link().返回: 如果後置條件不能建立,返回一個表示失敗原因的系統錯誤代碼,否則返回 0.
後置條件:
exists(to_p) && exists(from_p) && equivalent(to_p, from_p)to_p所解析的文件或目錄的內容不變。[注: 有些操作系統不支持硬鏈接或只對常規文件支持硬鏈接。有些操作系統則限制每個文件的鏈接數量。有些文件系統不支持硬鏈接 - 如用於軟盤、存儲卡和閃存盤的 FAT 系統。因此如果代碼的移植性是關鍵,則應避免硬鏈接。 -- 注完]
template <class Path1, class Path2>
void create_hard_link(const Path1& to_p, const Path2& from_p);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用: 如
system_error_code ec( create_hard_link( to_p, from_p ) );拋 出:
basic_filesystem_error<Path1, Path2>如果ec不為零。
template <class Path1, class Path2>
error_code create_symlink(const Path1& to_p, const Path2& from_p, error_code& ec);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用: 建立後置條件,如 POSIX
symlink().返回: 如果後置條件不能建立,則返回表示失敗原因的系統錯誤代碼,否則返回 0.
後 置條件:
from_p解析為一個符號鏈接文件,包含一個對to_p的未指定表示。[注: 有些操作系統不支持符號鏈接或只對常規文件支持。因此如果代碼的可移植性是關鍵,則應避免符號鏈接。-- 注完]
template <class Path1, class Path2>
void create_symlink(const Path1& to_p, const Path2& from_p);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用: 如
system_error_code ec( create_symlink( to_p, from_p ) );拋 出:
basic_filesystem_error<Path1, Path2>如果ec不為零。
template <class Path> void remove(const Path& p, system::error_code & ec = singular );
作用: 刪除文件
p, 如 POSIXremove(). 如果底層實現沒有錯誤報告或如果status(p).type() == file_not_found, 則:
- 如果
ec !=singular, 則ec.clear().否則,
- 如果
ec !=singular, 則設置ec以表示該錯誤。- 否則,拋出
basic_filesystem_error<Path>以表示該錯誤。如果ec !=singular, 則ec.clear()後置條件:
!exists(p)拋出: 參見 作用。
[注: 對於符號鏈接,其本身被刪除,而不是其所解析的文件被刪除。-- 注完]
template <class Path> unsigned long remove_all(const Path& p);
作用: 遞歸刪除 p 中的內容如果它存在,則刪除
p文件本身,如 POSIXremove().返回: 刪除文件的數量。
後置條件:
!exists(p)[注: 對於符號鏈接,其本身被刪除,而不是其所解析的文件被刪除。-- 注完]
template <class Path1, class Path2> void rename(const Path1& from_p, const Path2& to_p);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用: 將
from_p改名為to_p, 如 POSIXrename().後置條件:
!exists(from_p) && exists(to_p), 且原來名為from_p的文件的內容和屬性不變。[注: 如果
from_p和to_p為同一文件,則無操作。否則,如果to_p為已有文件,則被刪除。對於符號鏈接,其本身被改名,而不是其所指文件被改名。-- 注完]
template <class Path1, class Path2> void copy_file(const Path1& from_fp, const Path2& to_fp);
要求:
Path1::external_string_type和Path2::external_string_type為相同類型。作用:
from_fp所代表文件的內容和屬性被複製至to_fp所代表的文件。拋出:
basic_filesystem_error<Path>如果from_fp.empty() || to_fp.empty() ||!exists(from_fp) || !is_regular(from_fp) || exists(to_fp)
template <class Path> Path complete(const Path& p, const Path& base=initial_path<Path>());
作用: 從
p和base組合一個完整的路徑,使用以下規則:
p.has_root_directory()!p.has_root_directory()p.has_root_name()p前提條件不滿足 !p.has_root_name()base.root_name()
/ pbase / p返回: 組成的路徑。
後置條件: 對於返回的路徑
rp,rp.is_complete()為 true.拋出: 如果
!(base.is_complete() && (p.is_complete() || !p.has_root_name()))[注: 如果需要可移植的行為,請使用 complete(). 如果需要與操作系統相關的行為,則使用 system_complete().
如果要處理程序內部創建的路徑,則應使用可移植行為,特別是如果程序要在所有操作系統上表現出相同的行為。
如果要處理由用戶輸入的路徑,或向用戶輸出,或用戶期望的類似行為,則應使用與操作系統相關的行為。-- 注完]
template <class Path> Path system_complete(const Path& p);
作用: 從
p組成一個完整路徑,使用與操作系統解析一個傳給標準庫 open 函數的路徑的相同規則。返回: 組成的路徑。
後置條件: 對於返回的路徑
rp,rp.is_complete()為 true.拋出: 如果
p.empty().[注: 對於 POSIX,
system_complete(p)具有與complete(p, current_path())相同的語義。對於 Windows, 如果
p.is_complete() || !p.has_root_name()或p和base具有相同的root_name(),則system_complete(p)具有與complete(ph, current_path())相同的語義。否則類似於complete(p, kinky), 其中kinky為p.root_name()驅動器的當前目錄。它是該驅動器最後一次被設置的當前目錄,因此可能是命 令處理器所運行的上一個程序所遺留下來的!雖然這些語義常常被用到,但也是非常容易出錯的。有關用法的建議,請見 complete() 註解。-- 注完]
template <class Path> bool create_directories(const Path & p);
要求:
p.empty() ||
對於所有 px: px == p || is_parent(px, p): is_directory(px) || !exists( px )返回: 達成後置條件之前的
!exists(p)值。後置條件:
is_directory(p)拋出:
basic_filesystem_error<Path>如果exists(p) && !is_directory(p)
不贊成使用的便利函數以下函數已被 template <class Path> typename Path::string_type extension(const Path & p);
template <class Path> typename Path::string_type basename(const Path & p);
template <class Path>
|
<fstream>
的增加以 下新增的規格是經過仔細考慮,以避免破壞在常用操作環境,如 POSIX, Windows, 和 OpenVMS 中的已有代碼。有關避免在其它環境中破壞已有代碼,請參見 對
<fstream>實現的建議,尤其是在那些允許斜槓號出現在 文件名中的操作系統。[注: 來自 對實現的要求 中的"do-the-right-thing" 規則被應用於頭文件
<fstream>.以 下給出的重載是新增的,而不是替換已有函數。這樣保護了那些依賴於到
const char*的自動轉換的已有代碼(可能使用了自已的路徑類)。-- 注完]
在 27.8.1.1 Class template basic_filebuf [lib.filebuf] 概要的第1段,增加函數:
template <class Path> basic_filebuf<charT,traits>* open(const Path& p, ios_base::openmode mode);
在 27.8.1.3 Member functions [lib.filebuf.members], 將上述增加到第2段的簽名中,並替換句子:
It then opens a file, if possible, whose name is the NTBS s (「as if」 by calling
std::fopen(s ,modstr )).
為:
It then opens, if possible, the file that
porpath(s)resolves to, 「as if」 by callingstd::fopen()with a second argument of modstr.
在 27.8.1.5 Class template basic_ifstream [lib.ifstream] 概要的第1段,增加函數:
template <class Path> explicit basic_ifstream(const Path& p, ios_base::openmode mode = ios_base::in);
template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::in);
在 27.8.1.6 basic_ifstream constructors [lib.ifstream.cons] 中 增加上述構造函數到第2段的簽名中,並替換
rdbuf()->open(s, mode | ios_base::in)
為
rdbuf()->open(path(s), mode | ios_base::in)orrdbuf()->open(p, mode | ios_base::in)as appropriate
在 27.8.1.7 Member functions [lib.ifstream.members] 中增加上述 open 函數到第3段的簽名中,並替換
rdbuf()->open(s, mode | ios_base::in)
為
rdbuf()->open(path(s), mode | ios_base::in)orrdbuf()->open(p, mode | ios_base::in)as appropriate
在 27.8.1.8 Class template basic_ofstream [lib.ofstream] 概要的第1段,增加函數:
template <class Path> explicit basic_ofstream(const Path& p, ios_base::openmode mode = ios_base::out);
template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::out);
在 27.8.1.9 basic_ofstream constructors [lib.ofstream.cons] 中 增加上述構造函數到第2段的簽名中,並替換
rdbuf()->open(s, mode | ios_base::out)
為
rdbuf()->open(path(s), mode | ios_base::out)orrdbuf()->open(p, mode | ios_base::out)as appropriate
在 27.8.1.10 Member functions [lib.ofstream.members] 中增加上述 open 函數到第3段的簽名中,並替換
rdbuf()->open(s, mode | ios_base::out)
為
rdbuf()->open(path(s), mode | ios_base::out)orrdbuf()->open(p, mode | ios_base::out)as appropriate
在 27.8.1.11 Class template basic_fstream [lib.fstream] 概要第1段,增加函數:
template <class Path> explicit basic_fstream(const Path& p, ios_base::openmode mode = ios_base::in|ios_base::out);
template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::in|ios_base::out);
在 27.8.1.12 basic_fstream constructors [lib.fstream.cons] 中 增加上述構造函數到第2段的簽名中,並替換
rdbuf()->open(s, mode)
為
rdbuf()->open(path(s), mode)orrdbuf()->open(p, mode)as appropriate
在 27.8.1.13 Member functions [lib.fstream.members] 中增加上述 open 函數到第3段的簽名中,並替換
rdbuf()->open(s, mode)
為
rdbuf()->open(path(s), mode)orrdbuf()->open(p, mode)as appropriate
建 議文本結束。
該表由以 Boost 實現編譯的程序生成。
有底色的項表示 POSIX 和 Windows
實現會產生不同結果。上方的值為
POSIX 結果而下方的值為 Windows 結果。
| 構造函數參數 | 遍歷所找到的元素 | string() |
file_ |
root_ |
root_ |
root_ |
relative_ |
parent_ |
filename() |
"" |
"" |
"" |
"" |
"" |
"" |
"" |
"" |
"" |
"" |
"." |
"." |
"." |
"." |
"" |
"" |
"" |
"." |
"" |
"." |
".." |
".." |
".." |
".." |
"" |
"" |
"" |
".." |
"" |
".." |
"foo" |
"foo" |
"foo" |
"foo" |
"" |
"" |
"" |
"foo" |
"" |
"foo" |
"/" |
"/" |
"/" |
"/" |
"/" |
"" |
"/" |
"" |
"" |
"/" |
"/foo" |
"/","foo" |
"/foo" |
"/foo" |
"/" |
"" |
"/" |
"foo" |
"/" |
"foo" |
"foo/" |
"foo","." |
"foo/" |
"foo/" |
"" |
"" |
"" |
"foo/" |
"foo" |
"." |
"/foo/" |
"/","foo","." |
"/foo/" |
"/foo/" |
"/" |
"" |
"/" |
"foo/" |
"/foo" |
"." |
"foo/bar" |
"foo","bar" |
"foo/bar" |
"foo/bar" |
"" |
"" |
"" |
"foo/bar" |
"foo" |
"bar" |
"/foo/bar" |
"/","foo","bar" |
"/foo/bar" |
"/foo/bar" |
"/" |
"" |
"/" |
"foo/bar" |
"/foo" |
"bar" |
"///foo///" |
"/","foo","." |
"///foo///" |
"///foo///" |
"/" |
"" |
"/" |
"foo///" |
"///foo" |
"." |
"///foo///bar" |
"/","foo","bar" |
"///foo///bar" |
"///foo///bar" |
"/" |
"" |
"/" |
"foo///bar" |
"///foo" |
"bar" |
"/." |
"/","." |
"/." |
"/." |
"/" |
"" |
"/" |
"." |
"/" |
"." |
"./" |
".","." |
"./" |
"./" |
"" |
"" |
"" |
"./" |
"." |
"." |
"/.." |
"/",".." |
"/.." |
"/.." |
"/" |
"" |
"/" |
".." |
"/" |
".." |
"../" |
"..","." |
"../" |
"../" |
"" |
"" |
"" |
"../" |
".." |
"." |
"foo/." |
"foo","." |
"foo/." |
"foo/." |
"" |
"" |
"" |
"foo/." |
"foo" |
"." |
"foo/.." |
"foo",".." |
"foo/.." |
"foo/.." |
"" |
"" |
"" |
"foo/.." |
"foo" |
".." |
"foo/./" |
"foo",".","." |
"foo/./" |
"foo/./" |
"" |
"" |
"" |
"foo/./" |
"foo/." |
"." |
"foo/./bar" |
"foo",".","bar" |
"foo/./bar" |
"foo/./bar" |
"" |
"" |
"" |
"foo/./bar" |
"foo/." |
"bar" |
"foo/.." |
"foo",".." |
"foo/.." |
"foo/.." |
"" |
"" |
"" |
"foo/.." |
"foo" |
".." |
"foo/../" |
"foo","..","." |
"foo/../" |
"foo/../" |
"" |
"" |
"" |
"foo/../" |
"foo/.." |
"." |
"foo/../bar" |
"foo","..","bar" |
"foo/../bar" |
"foo/../bar" |
"" |
"" |
"" |
"foo/../bar" |
"foo/.." |
"bar" |
"c:" |
"c:" |
"c:" |
"c:" |
"" |
"" |
"" |
"c:" |
"" |
"c:" |
"c:/" |
"c:","." |
"c:/" |
"c:/" |
"" |
"" |
"" |
"c:/" |
"c:" |
"." |
"c:foo" |
"c:foo" |
"c:foo" |
"c:foo" |
"" |
"" |
"" |
"c:foo" |
"" |
"c:foo" |
"c:/foo" |
"c:","foo" |
"c:/foo" |
"c:/foo" |
"" |
"" |
"" |
"c:/foo" |
"c:" |
"foo" |
"c:foo/" |
"c:foo","." |
"c:foo/" |
"c:foo/" |
"" |
"" |
"" |
"c:foo/" |
"c:foo" |
"." |
"c:/foo/" |
"c:","foo","." |
"c:/foo/" |
"c:/foo/" |
"" |
"" |
"" |
"c:/foo/" |
"c:/foo" |
"." |
"c:/foo/bar" |
"c:","foo","bar" |
"c:/foo/bar" |
"c:/foo/bar" |
"" |
"" |
"" |
"c:/foo/bar" |
"c:/foo" |
"bar" |
"prn:" |
"prn:" |
"prn:" |
"prn:" |
"" |
"" |
"" |
"prn:" |
"" |
"prn:" |
"c:\" |
"c:\" |
"c:\" |
"c:\" |
"" |
"" |
"" |
"c:\" |
"" |
"c:\" |
"c:foo" |
"c:foo" |
"c:foo" |
"c:foo" |
"" |
"" |
"" |
"c:foo" |
"" |
"c:foo" |
"c:\foo" |
"c:\foo" |
"c:\foo" |
"c:\foo" |
"" |
"" |
"" |
"c:\foo" |
"" |
"c:\foo" |
"c:foo\" |
"c:foo\" |
"c:foo\" |
"c:foo\" |
"" |
"" |
"" |
"c:foo\" |
"" |
"c:foo\" |
"c:\foo\" |
"c:\foo\" |
"c:\foo\" |
"c:\foo\" |
"" |
"" |
"" |
"c:\foo\" |
"" |
"c:\foo\" |
"c:\foo/" |
"c:\foo","." |
"c:\foo/" |
"c:\foo/" |
"" |
"" |
"" |
"c:\foo/" |
"c:\foo" |
"." |
"c:/foo\bar" |
"c:","foo\bar" |
"c:/foo\bar" |
"c:/foo\bar" |
"" |
"" |
"" |
"c:/foo\bar" |
"c:" |
"foo\bar" |
<fstream>
實現的建議對
於接受 const char*
參數的函數的語義的改動會破壞已有代碼,但是僅會發生在那些不支持 隱
式接受原生格式路徑名 或允許斜槓號用於文件名的操作系統中。因此在 POSIX, Windows,
和 OpenVMS 上,如果實現遵守推薦行為就不會有問題。
對
於多數 Filesystem 庫,並沒有已有代碼,所以在文件名中使用斜槓號的問題並不會發生。新代碼只須使用帶有 path_format_t 參數的
basic_path 構造函數。為保護那些在文件名中使用了斜槓號的已有 fstream
代碼,實現可能要提供一個機制,如某個宏,來控制選用舊的行為。
TR
的前頁已要求具體實現要提供一個機制,如某個宏,來控制頭文件選用舊的行為(為了保護已有代碼)或新的行為(用於新代碼以及從其它系統移植來的代碼)。因
為 Filesystem 庫的其餘部分的使用與 <fstream>
新增內容無關,所以建議受到影響的實現可以與其它TR特性分開,單獨禁用 <fstream>
新增內容。
另
一種被拒絕的選擇是,在名字空間 filesystem 中提供新的 fstream
類,它們派生自當前的類,覆蓋各個構造函數和 open 函數,接受路徑名參數,並提供其它重載。在 Lillehammer LWG members
中說明了這一方法的缺點,感覺上它的開銷高於所獲得的好處。
This Filesystem Library is dedicated to my wife, Sonda, who provided the support necessary to see both a trial implementation and the proposal itself through to completion. She gave me the strength to continue after a difficult year of cancer treatment in the middle of it all.
Many people contributed technical comments, ideas, and suggestions to the Boost Filesystem Library. See http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements.
Dietmar Kuhl contributed the original Boost Filesystem Library directory_iterator design. Peter Dimov, Walter Landry, Rob Stewart, and Thomas Witt were particularly helpful in refining the library.
The create_directories, extension, basename, and replace_extension functions were developed by Vladimir Prus.
Howard Hinnant and John Maddock reviewed a draft of the proposal, and identified a number of mistakes or weaknesses, resulting in a more polished final document.
| [ISO-POSIX] | ISO/IEC 9945:2003, IEEE Std 1003.1-2001, and The Open Group Base Specifications, Issue 6. Also known as The Single UnixR Specification, Version 3. Available from each of the organizations involved in its creation. For example, read online or download from www.unix.org/single_unix_specification/. The ISO JTC1/SC22/WG15 - POSIX homepage is www.open-std.org/jtc1/sc22/WG15/ |
| [Abrahams] | Dave Abrahams, Error and Exception Handling, www.boost.org/more/error_handling.html |
c Copyright Beman Dawes, 2002, 2006, 2007
Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt
Revised 13
October 2008