一、文件系统(c++17)
1、文件系统库
c++17中的std::filesystem提供了在文件系统与其组件,如路径、常规文件与目录上进行操作的方法。
File文件:持有数据的文件系统对象,能被写入或读取。文件有名称和属性,属性之一是文件类型。
Path路径:标识文件所处位置的一系列元素,可能包含文件名。
路径类:
namespace fs = std::filesystem//定义名字空间别名;
fs::path p{"fileName.cpp"};//定义包含cpp文件的路径变量p;
路径分为绝对路径和相对路径。
//绝对路径
D:\api-test //包含完整的路径和驱动器符号;
//相对路径
./api-test //当前路径下的文件或文件夹;
../api-test //前一层目录下的文件或文件夹;
定义路径变量的例子
namespace fs = std::filesystem
//字符串中的反斜杠要被转义,通常windows操作系统用的反斜杠“\”
fs::path p1{"d:\\workplace\\test.cpp"};
//windows也支持正斜杠;
fs::path p2{"d/workplace/test.cpp"};
//使用原始字符串字面量,此时不需要使用转义;
fs::path p3{R"(d:\workplace\test.cpp)"};
2、path类及其操作
部分重要的成员函数 | 说明 | |
---|---|---|
path(string) | 构造函数 | |
assign(string):path& | 为路径对象赋值 | |
连接 | append(type p):path& | 将p追加到路径后。type是string、path或const char*。等价于 /= 运算符;自动添加目录分隔符 |
concat(type p):path& | 将p追加到路径后,type是string、path或const char*。等价于 += 运算符;不自动添加目录分隔符 | |
修 改器 | clear():void | 清空存储的路径名 |
remove_filename():path& | 从给定路径中移除文件名 | |
replace_filename(const path& replacement):path& | 以replacement替换文件名 | |
分 解 | root_name():path | 返回通用格式路径的根名 |
root_directory():path | 返回通用格式路径的根目录 | |
root_paht():path | 返回路径的根路径,等价于 root_name)/root_directory() | |
relative_path():path | 返回相对于root-path的路径 | |
parent_path():path | 返回父目录的路径 | |
filename():path | 返回路径中的包含的文件名 | |
stem():path | 返回路径中包含的文件名,不包括文件的扩展名 | |
extension():path | 返回路径中包含的文件名的扩展名 | |
查 询 | empty():bool | 检查路径是否为空 |
has_xxx():bool | 其中xxx是上面分解类别中的函数名,这些函数检查路径是否含有相应路径元素 |
部分重要的非成员函数 | 说明 | |
operator/(const path& lhs, const path& rhs | 以/目录分隔符连接两个路径成分lhs和rhs。譬如 path p{"C:"}; p = p / "Users" / "batman"; | |
operator <<, >> (path p) | 进行路径p上的流输入或输出 | |
文 件 类型 | s_regular_file(const path& p):bool | 检查路径是否是常规文件 |
is_directory(const path& p):bool | 检查路径是否是目录 | |
is_empty(const path& p):bool | 检查给定路径是否指代一个空文件或目录 | |
查询 | current_path():path current_path(const path& p):void | 返回当前工作目录的绝对路径(类似linux指令pwd) 更改当前路径为p(类似linux指令cd) |
file_size(const path& p):uintmax_t | 对于常规文件p,返回其大小;尝试确定目录(以及其他非常规文件)的大小的结果是由编译器决定的 | |
space(const path& p):space_info | 返回路径名p定位于其上的文件系统信息。space_info中有三个成员:capacity--文件系统的大小(字节),free--文件系统的空闲空间(字节),available--普通进程可用的空闲空间(小于或等于free) | |
status(const path& p):file_status | 返回p所标识的文件系统对象的类型与属性。返回的file_status是一个类,其中包含文件的类型和权限 | |
修改 | remove(const path&p):bool remove_all(const path& p):uintmax_t | 删除路径p所标识的文件或空目录 递归删除p的内容(若它是目录)及其子目录的内容,然后删除p自身,返回被删文件及目录数量 |
rename(const path& old_p,const path& new_p):void | 移动或重命名old_p所标识的文件系统对象到new_p(类似linux下的mv) | |
copy(const path& from,const path& to):void | 复制文件与目录。另外一个函数bool copy_file(from,to)拷贝单个文件 | |
create_directory(const path& p):bool create_directories(const path& p):bool | 创建目录p(父目录必须已经存在),若p已经存在则函数无操作 创建目录p(父目录不一定存在),若p已经存在,则函数无操作 |
二、文件I/O流的基本用法
1、输入输出类介绍(文件类操作对比)
c++ | c | ||
Header File | file input | ifstream(i:input; f:file | stdio.h |
file output | ofstream(o:output; f:file) | ||
file input & output | fstream | ||
Read / Write | read from file | >>; get(); get(char); get(char*); getline(); read(char* streamsize); | fscanf(); fgets(char* ,size_t ,FILE*); fread(void* ptr,size,nitems,FILE* stream); |
write to file | <<; put(char),put(int); write(const char*, streamsize); flush() | fprintf(); fwrite(const void* ptr,size,nitems,FILE* stream); fputs(const char*, FILE* ); | |
Status test | eof(); bad(); good(); fail() | feof(); ferror(); |
c++的流类主要有五类:
a、流基类(ios_base和ios)
b、标准输入输出流类(istream/ostream/iostream)
c、字符串流类(istringstream/ostringstream)
d、文件流类(ifstream/ofstream/fstream)
e、缓冲区类(streambuf/stringbuf/filebuf)
标准输入输出流对象cin和cout分别是类istream和ostream的实例。
字符串流:将各种不同的数据格式化输出到一个字符串中,可以使用I/O操纵器控制格式;反之也可以从字符串中读入各种不同的数据。
c++的I/O流是有内部缓冲区的。
#include <iostream>
using namespace std;
int main()
{
char c;
int i = 0;
do{
c = cin.get();//每次读取一个字符,并把其余的字符留在输入对列中;
cout << ++i << ": " << static_cast<int>(c) << endl;
}while(c != 'q');
return 0;
}
2、向文件中写入数据
ofstream可向文本中写数据,具体步骤如下:
//将hello、换行符和85保存到test.txt中
#include <fstream>
int main()
{
std::ofstream op{"test.txt"};
op << "hello" << "\n" << 85;
return 0;
}
3、从文件读数据
用ifstream从文本文件中读数据,步骤如下:
其中检测文件是否成功打开用fail()函数,若文件没有被打开,返回true。
检测文件是否到末尾,用eof()函数。
//将hello、换行符和85从test.txt读入;
#include <iostream>
#include <fstream>
int main()
{
std::ifstream p{"test.txt"};
if(p.fail())
{
std::cout << "read file error!" <<std::endl;
return 1;
}
char x;
while(p.get(x).eof())
{
std::cout << x << std::endl;
}
std::cin.get();
return 0;
}