目录
- C++文件操作
- 1. 使用系统函数读写
- linux平台
- 判断是否存在
- 创建文件 create()接口
- 打开文件 open()接口
- 读取文件 read()接口
- 写文件 write()接口
- 关闭文件 close()接口
- 调整读写文件的位置(偏移量)lseek()接口
- 获取文件基本信息
- 操作文件状态 fcntl函数
- windows平台
- 打开文件
- 读取文件
- 关闭文件
- 判断文件是否存在
- 获取文件基本信息
- 2. 使用C++ fstream库
- 2.1 文件对象的定义
- 2.2 打开文件
- 2.3 读写文件
- 2.3.1 以流的方式读写
- 2.3.2 以成员函数的方式读写
- 2.4 指针移动
- 2.5 关闭文件
- 3. 使用C语言库函数
C++文件操作
参考:全网最详细C/C++文件读写总结
1. 使用系统函数读写
linux平台
判断是否存在
头文件:unistd.h
接口:int access(const char* __path, int __mode);
如果文件存在返回值为0,否则返回值不为0。接口调用过程中,会将错误码保存在全局变量errno中,接口调用结束可通过判断errno的值,来进一步判断文件是确实不存在,还是由于权限限制访问文件失败。
uint32_t BasicFileSystem::FileExists(std::string_view path)
{if (access(path.data(), F_OK) != 0) {if (errno != ENOENT) {LOG_ERROR("BasicFileSystem-{}: fail to access, error({})", __func__, errno);}return errno;}return 0;
}
创建文件 create()接口
头文件:fcntl.h
接口:int creat(const char* __path, mode_t __mode);
创建成功时,返回新创建文件的fd;失败时,返回-1,并设置全局变量errno。
打开文件 open()接口
头文件:fcntl.h
接口:int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
返回值:文件描述符 fd
参数1:文件绝对路径;
参数2 flags:指定文件打开方式,包括只读O_RDONLY | O_WRONLY只写 | O_RDWR读写 | O_CREAT不存在时自动创建 | O_TRUNC | O_APPEND追加等;
参数3 mode:文件的权限信息,只有flags为O_CREAT创建新文件时才会使用参数mode;
#include <fcntl.h>std::string_view path;
int fd = open(path.data(), flags, mode); // fd < 0 说明打开文件失败
读取文件 read()接口
头文件:unistd.h
接口:
ssize_t read(int __fd, void* __buf, size_t __count);
ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
返回值:读取的字节数,返回值<0,说明读取失败,错误码将保存在全局变量errno中。
参数1:文件描述符;
参数2:保存读取结果的缓冲区;
参数3:想要读取的字节数;
参数4:开始读取的位置(偏移量);
写文件 write()接口
头文件:unistd.h
接口:
ssize_t write(int __fd, const void* __buf, size_t __count);
ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset);
参数buf 所指的内容写入count 个字节到参数fd 所指的文件内。
返回值:写入的字节数,返回值<0,说明写入失败,错误码将保存在全局变量errno中。
思考:利用read、write每次读或写1个Byte与利用gets和puts每次读或写1个Byte哪一种方式速度更快?
read和write函数的使用
关闭文件 close()接口
头文件:unistd.h
接口声明:int close(int __fd);
返回值:关闭成功返回0,否则关闭失败。
调整读写文件的位置(偏移量)lseek()接口
头文件:unistd.h
接口:off_t lseek(int __fd, off_t __offset, int __whence);
将fd所表示的文件的读写位置,移动到offset设置的位置,起始偏移位置由whence决定。
whence有如下三种:
/** Seek to an absolute offset. */
#define SEEK_SET 0
/** Seek relative to the current offset. */
#define SEEK_CUR 1
/** Seek relative to the end of the file. */
#define SEEK_END 2
获取文件基本信息
使用stat指令获取文件基本信息:
Linux命令:stat
Linux基础命令-stat显示文件的状态信息
代码中使用stat接口获取文件基本信息:Linux:st_mode详细分析
stat接口头文件:#include <sys/stat.h>
接口:
int stat(const char* __path, struct stat* __buf);
int fstat(int __fd, struct stat* __buf);
成功时,返回值为0,结果保存在stat结构体中;失败时,返回值不为0,错误码将保存在全局变量errno中。
使用mode值获得文件类型和权限信息,调用S_ISREG(mode)宏接口:#include<linux/stat.h>
操作文件状态 fcntl函数
int flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
注:F_GETFL表示获取文件状态
F_SETFL表示设置文件状态
windows平台
打开文件
读取文件
关闭文件
判断文件是否存在
_access_s,_waccess_s
获取文件基本信息
2. 使用C++ fstream库
2.1 文件对象的定义
fstream提供三种类,实现C++对文件的操作:
ofstream:写操作,由ostream引申而来
ifstream:读操作,由istream引申而来
fstream :同时读写操作,他是前两者的父类,由iostream引申而来
创建一个文件对象:
fstream file;
2.2 打开文件
文件的打开类型:
ios::in 为输入(读)而打开文件;
ios::out 为输出(写)而打开文件;
ios::ate 初始位置:文件尾;
ios::app 所有输出附加在文件末尾;
ios::trunc 如果文件已存在则先删除该文件;
ios::binary 二进制方式;
ios::nocreate:不建立文件,所以文件不存在时打开失败;
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败;
例如,如果我们想要以二进制方式打开文件"example.bin" 来写入一些数据,我们可以通过以下方式调用成员函数open()来实现:
方法一:
ofstream file;
file.open ("example.bin", ios::out | ios::app | ios::binary);方法二:
ofstream file ("example.bin", ios::out | ios::app | ios::binary);
通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了:
接口:bool is_open();
!file.is_open() || !file 两种方式任选其一即可。
2.3 读写文件
2.3.1 以流的方式读写
读文件:使用 >>
写文件:使用 <<
#include <iostream>
#include <fstream>
#include <string>using namespace std;int main()
{fstream file;file.open("2.txt", ios::out | ios::in);if (!file || !file.is_open()){cout << "打开失败" << endl;return;}const char* str2 = "HelloWorld";file << str2 << " " << 4; // 写文件file.seekg(0, ios::beg); // 将读写指针移动到起始int num = 0; char str[20] = " "; file >> str >> num; // 读文件,每一个>>符号每次只能读出由空格、回车等白色字符分开的一块内容cout << str << num << endl;int n = file.tellg(); // 文件指针位置cout << n << endl;file.close(); // 关闭文件return 0;
}
2.3.2 以成员函数的方式读写
读文件:
// 至多读取n字节的内容到缓存s中
file.read(char_type* __s, streamsize __n);
// 按行读取
// 作用是从istream中读取至多n个字符保存在s对应的数组中。
// 即使还没读够n个字符,如果遇到换行符’\n’则读取终止。
// 读取过程中,相比>>符号的读取方式,会将白色字符也一并读取出来。
file.getline(char_type* __s, streamsize __n);
// 按元素读取
// 挨个元素读取,空白字符包括换行符将被视为字符的一种,也会被读取出来。
char c = file.get();
file.get(char_type& __c);
// 至多读取n个元素,空白字符包括换行符将被视为字符的一种,也会被读取出来。
file.get(char_type* __s, streamsize __n);
写文件:
file.write(,大小)
2.4 指针移动
文件指针位置的用法:
ios::beg 文件头
ios::end 文件尾
ios::cur 当前位置
例子:
file.seekg(0,ios::beg); //让文件指针定位到文件开头
file.seekg(0,ios::end); //让文件指针定位到文件末尾
file.seekg(10,ios::cur); //让文件指针从当前位置向文件末方向移动10个字节
file.seekg(-10,ios::cur); //让文件指针从当前位置向文件开始方向移动10个字节
file.seekg(10,ios::beg); //让文件指针定位到离文件开头10个字节的位置文件指针的获取:
int pos = tellg(); // 相比ios::beg的字节数
2.5 关闭文件
file.close();
c++文件读写(很全)
3. 使用C语言库函数
打开文件:FILE *fopen(const char filename, const char mode);
写文件:size_t fwrite(const void buffer, size_t size, size_t count, FILE fd);
读文件:size_t fread(void *buffer, size_t size, size_t count, FILE *fd);
关闭文件:close(fd);