滨州市滨城区建设局网站,专业的大连网站建设,私人网站制作,摄影网站的模板一、文件流类概述
C 标准库提供了三个主要的文件流类#xff1a;
ifstream (输入文件流)#xff1a;用于从文件读取数据ofstream (输出文件流)#xff1a;用于向文件写入数据fstream (文件流)#xff1a;既可读又可写
这些类都继承自 iostream 类#xff0c;因此可以使用 …一、文件流类概述
C 标准库提供了三个主要的文件流类
ifstream (输入文件流)用于从文件读取数据ofstream (输出文件流)用于向文件写入数据fstream (文件流)既可读又可写
这些类都继承自 iostream 类因此可以使用 和 操作符进行格式化I/O操作。
二、文件打开与关闭
1. 打开文件
#include fstream
using namespace std;// 方法1先声明再打开
ofstream outFile;
outFile.open(output.txt);// 方法2声明时直接打开
ifstream inFile(input.txt);// 方法3使用fstream
fstream ioFile;
ioFile.open(data.txt, ios::in | ios::out);2. 文件打开模式模式标志描述ios::in以读取方式打开ios::out以写入方式打开ios::app追加模式所有写入都追加到文件末尾ios::ate打开文件后定位到文件末尾ios::trunc如果文件存在则清空内容ios::binary二进制模式组合示例
// 以写入和追加模式打开
ofstream logFile(log.txt, ios::out | ios::app);// 以读写和二进制模式打开
fstream dataFile(data.dat, ios::in | ios::out | ios::binary);3. 关闭文件
outFile.close();
inFile.close();
ioFile.close();注意虽然流对象析构时会自动关闭文件但显式关闭是个好习惯。
三、文件状态检查
ifstream file(data.txt);if (file.is_open()) {// 文件成功打开
} else {// 文件打开失败
}// 检查流状态
if (file.good()) {// 流状态良好
}if (file.fail()) {// 操作失败非致命错误
}if (file.bad()) {// 严重错误
}if (file.eof()) {// 到达文件末尾
}四、文本文件操作
1. 写入文本文件
ofstream out(output.txt);
if (out.is_open()) {out 第一行文本 endl;out 123 3.14 endl;out 这是另一行文本 endl;out.close();
} else {cerr 无法打开文件! endl;
}2. 读取文本文件
逐行读取
ifstream in(input.txt);
string line;
if (in.is_open()) {while (getline(in, line)) {cout line endl;}in.close();
}逐词读取
ifstream in(input.txt);
string word;
if (in.is_open()) {while (in word) {cout word endl;}in.close();
}格式化读取
ifstream in(data.txt);
int id;
double value;
string name;if (in.is_open()) {while (in id value name) {cout ID: id , Value: value , Name: name endl;}in.close();
}五、二进制文件操作
1. 写入二进制数据
struct Record {int id;char name[50];double salary;
};Record emp {101, John Doe, 4500.50};ofstream out(employees.dat, ios::binary);
if (out.is_open()) {out.write(reinterpret_castchar*(emp), sizeof(Record));out.close();
}2. 读取二进制数据
Record emp;
ifstream in(employees.dat, ios::binary);
if (in.is_open()) {in.read(reinterpret_castchar*(emp), sizeof(Record));cout ID: emp.id endl;cout Name: emp.name endl;cout Salary: emp.salary endl;in.close();
}3. 二进制文件随机访问
fstream file(data.dat, ios::in | ios::out | ios::binary);// 写入多个记录
Record records[3] {{101, Alice, 5000},{102, Bob, 6000},{103, Charlie, 7000}
};file.write(reinterpret_castchar*(records), 3 * sizeof(Record));// 直接读取第二个记录
Record emp;
file.seekg(1 * sizeof(Record), ios::beg);
file.read(reinterpret_castchar*(emp), sizeof(Record));// 修改第三个记录
emp {103, David, 7500};
file.seekp(2 * sizeof(Record), ios::beg);
file.write(reinterpret_castchar*(emp), sizeof(Record));file.close();六、文件定位
1. 获取当前位置
streampos pos file.tellg(); // 获取读取位置
streampos pos file.tellp(); // 获取写入位置2. 设置位置
// 绝对定位
file.seekg(0, ios::beg); // 移动到文件开头
file.seekg(0, ios::end); // 移动到文件末尾// 相对定位
file.seekg(10, ios::cur); // 从当前位置向前移动10字节
file.seekg(-5, ios::cur); // 从当前位置向后移动5字节七、实用文件操作函数
1. 检查文件是否存在
#include sys/stat.hbool fileExists(const string filename) {struct stat buffer;return (stat(filename.c_str(), buffer) 0);
}2. 获取文件大小
streampos getFileSize(const string filename) {ifstream file(filename, ios::ate | ios::binary);return file.tellg();
}3. 复制文件
bool copyFile(const string source, const string dest) {ifstream src(source, ios::binary);ofstream dst(dest, ios::binary);if (!src || !dst) {return false;}dst src.rdbuf();return true;
}4. 读取CSV文件
void readCSV(const string filename) {ifstream file(filename);string line;while (getline(file, line)) {stringstream ss(line);string cell;vectorstring row;while (getline(ss, cell, ,)) {row.push_back(cell);}// 处理行数据for (const auto val : row) {cout val \t;}cout endl;}
}八、错误处理最佳实践
void processFile(const string filename) {ifstream file(filename);if (!file) {cerr 错误无法打开文件 filename endl;perror(原因); // 打印系统错误信息return;}try {// 文件处理代码string line;while (getline(file, line)) {// 处理每一行}if (file.bad()) {throw runtime_error(读取文件时发生严重错误);}if (file.fail() !file.eof()) {throw runtime_error(文件格式错误);}} catch (const exception e) {cerr 错误: e.what() endl;file.close();return;}file.close();
}九、性能考虑缓冲区大小默认缓冲区大小可能不适合大文件操作可以自定义
char buffer[8192]; // 8KB缓冲区
ifstream file;
file.rdbuf()-pubsetbuf(buffer, sizeof(buffer));
file.open(largefile.dat);二进制 vs 文本二进制操作通常比文本操作更快特别是对于大量数据。内存映射文件对于极大文件考虑使用操作系统特定的内存映射文件API。十、C17 文件系统库
C17 引入了 filesystem 库提供了更高级的文件操作
#include filesystem
namespace fs std::filesystem;// 检查文件是否存在
if (fs::exists(test.txt)) {// 获取文件大小auto size fs::file_size(test.txt);// 复制文件fs::copy(source.txt, destination.txt);// 删除文件fs::remove(old_file.txt);// 遍历目录for (auto entry : fs::directory_iterator(.)) {cout entry.path() endl;}
}通过掌握这些文件操作技术您可以在C程序中高效地处理各种文件I/O任务。