13.5文件系统支持库
1.路径
可以使用 append()
方法或 operator/=
将组件附加到路径中。平台相关的路径分隔符会自动插入。
path p { R"(D:\Foo)" };
p.append("Bar");
p /= "Bar";
cout << p << endl;// D:\\Foo\\Bar\\Bar in Windows
可以使用concat()
或 operator+=
将字符串连接到现有路径。这不会插入任何路径分隔符
path p { R"(D:\Foo)" };
p.concat("Bar");
p += "Bar";
cout << p << endl;// D:\\FooBarBar
基于范围的 for循环可用于遍历路径的不同组件。
2.目录条目
路径仅表示文件系统中的目录或文件。路径可能会指向不存在的目录或文件。如果要查询文件系统上的实际目录或文件,需要从路径构造一个 directory_entry
。
3.辅助函数
还有一个完整的辅助函数集合。例如,可以使用 copy()
复制文件或目录;create_directory()
在文件系统上创建一个新目录; exists()
用来查询给定目录或文件是否存在;file_size()
获取一个文件的大小;last_write_time()
获取文件最后修改的时间;remove()
用来删除一个文件;temp_directory_path()
获取适合存储临时文件的目录;space()
用于查询文件系统上的可用空间等。
4.目录遍历
如果希望递归地遍历给定目录中的所有文件和子目录,可以使用 recursive_directory_iterator
。如果要开始迭代过程,那么需要一个指向第一个directory_entry
的迭代器。如果要知道何时停止迭代,那么需要一个结束迭代器。如果要创建起始迭代器,那么需要构造一个 recursive_directory_iterator
,并将要遍历目录的路径作为参数传递。如果要构造结束迭代器,那么需要默认构造一个recursive_directory_iterator
。如果要访问迭代器所引用的directory_entry
,请使用解引用操作符*
。遍历集合中的所有元素只需要使用++
运算符对迭代器递增,直到到达结束迭代器即可完成。注意,结束迭代器不再是集合的一部分,因此不再引用有效的 directory_entry
,并且不能被解引用。
void printDirectoryStructure(const fs::path& p)
{
if(!fs::exists(p)){
return;
}
fs::recursive_directory_iterator begin {p};
fs::recursive_directory_iterator end {};
for(auto iter{begin};iter!=end;++iter){
const string spacer(iter.depth()*2,' ');
auto entry{*iter};
if(fs::is_regular_file(entry)){
cout<<format("{}File: {} ({} bytes)",
spacer,entry.path().string(),fs::file_size(entry))<<endl;
}else if(fs::is_directory(entry)){
cout << format("{}Dir: {}",spacer, entry.path().string())<<endl;
}
}
}
还可以使用 directory_iterator
迭代目录的内容,并实现递归
void printDirectoryStructure(const fs::path& p, size_t level =0)
{
if(!fs::exists(p)){
return;
}
const string spacer(level*2,' ');
if(fs::is_regular_file(p)){
cout << format("{}File: {} ({} bytes)",
spacer,p.string(),fs::file_size(p)) << endl;
}else if(fs::is_directory(p)){
cout << format("{}Dir: {}", spacer, p.string()) << endl;
for (auto& entry : fs::directory_iterator{p}){
printDirectoryStructure(entry,level+1);
}
}
}