在c++开发中,文件操作是必备技能之一。本文将全面解析c++文件读写的核心概念、操作方法和最佳实践,包含丰富的代码示例。
一、文件操作核心类
c++通过<fstream>头文件提供三种核心类:
| 类名 | 功能描述 | 继承关系 |
|---|---|---|
| ofstream | 文件输出流(写操作) | 继承自ostream |
| ifstream | 文件输入流(读操作) | 继承自istream |
| fstream | 文件输入输出流(读写操作) | 继承自iostream |
二、文本文件操作
1. 写入文本文件
#include <fstream>
#include <string>
int main() {
// 创建输出流(默认覆盖模式)
std::ofstream outfile("data.txt");
if (!outfile) {
std::cerr << "文件创建失败!" << std::endl;
return 1;
}
// 写入不同类型数据
outfile << "用户日志\n";
outfile << "id: " << 1001 << "\n";
outfile << "余额: $" << 2450.75 << "\n";
// 自动关闭文件(raii)
return 0;
}
2. 读取文本文件
#include <fstream>
#include <iostream>
int main() {
std::ifstream infile("data.txt");
if (!infile.is_open()) {
std::cerr << "文件打开失败!" << std::endl;
return 1;
}
// 逐行读取
std::string line;
while (std::getline(infile, line)) {
std::cout << line << std::endl;
}
// 重置读取位置
infile.clear();
infile.seekg(0);
// 格式化读取
int id;
double balance;
infile.ignore(100, ':'); // 跳过"id: "
infile >> id;
infile.ignore(100, '$'); // 跳过"余额: $"
infile >> balance;
std::cout << "\n解析结果: id=" << id
<< ", 余额=" << balance << std::endl;
return 0;
}
三、二进制文件操作
1. 写入二进制数据
#include <fstream>
struct userdata {
int id;
double balance;
char name[32];
};
int main() {
userdata user = {1001, 2450.75, "张三"};
std::ofstream binfile("user.dat", std::ios::binary);
binfile.write(reinterpret_cast<char*>(&user), sizeof(user));
return 0;
}
2. 读取二进制数据
#include <fstream>
#include <iostream>
int main() {
std::ifstream binfile("user.dat", std::ios::binary);
if (!binfile) {
std::cerr << "二进制文件打开失败!" << std::endl;
return 1;
}
userdata user;
binfile.read(reinterpret_cast<char*>(&user), sizeof(user));
std::cout << "用户id: " << user.id << "\n"
<< "姓名: " << user.name << "\n"
<< "余额: " << user.balance << std::endl;
return 0;
}
四、文件打开模式详解
通过位或运算符组合多种模式:
| 模式标志 | 描述 |
|---|---|
| std::ios::in | 读模式(默认ifstream) |
| std::ios::out | 写模式(默认ofstream) |
| std::ios::app | 追加模式(不覆盖原有内容) |
| std::ios::ate | 打开后定位到文件末尾 |
| std::ios::trunc | 清空文件(默认) |
| std::ios::binary | 二进制模式 |
// 示例:以追加模式写入文本
std::ofstream logfile("app.log",
std::ios::out | std::ios::app);
// 示例:读写二进制文件(不截断)
std::fstream datafile("records.dat",
std::ios::binary |
std::ios::in |
std::ios::out);
五、错误处理机制
健壮的文件操作必须包含错误处理:
std::fstream file("critical.dat");
// 检查文件状态
if (file.fail()) {
std::cerr << "文件操作失败!" << std::endl;
}
// 详细错误诊断
if (!file) {
if (file.bad()) {
std::cerr << "不可恢复的错误" << std::endl;
} else if (file.eof()) {
std::cerr << "到达文件末尾" << std::endl;
} else if (file.fail()) {
std::cerr << "非致命错误(如格式错误)" << std::endl;
}
}
六、最佳实践与性能优化
1. raii管理资源
{
std::ofstream tmpfile("temp.txt");
// 文件在作用域结束时自动关闭
}
2. 高效文件复制
bool copyfile(const std::string& src, const std::string& dst) {
std::ifstream in(src, std::ios::binary);
std::ofstream out(dst, std::ios::binary);
if (!in || !out) return false;
const size_t buffer_size = 4096;
char buffer[buffer_size];
while (in.read(buffer, buffer_size)) {
out.write(buffer, buffer_size);
}
out.write(buffer, in.gcount()); // 写入剩余字节
return true;
}
3. c++17文件系统操作
#include <filesystem>
namespace fs = std::filesystem;
// 检查文件存在
if (fs::exists("data.txt")) {
// 获取文件大小
auto size = fs::file_size("data.txt");
// 重命名文件
fs::rename("old.txt", "new.txt");
}
七、应用案例:日志系统
class logger {
public:
logger(const std::string& filename)
: logfile(filename, std::ios::app) {}
~logger() { if (logfile) logfile.close(); }
void log(const std::string& message) {
if (!logfile) return;
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
logfile << std::put_time(std::localtime(&time), "%f %t")
<< " | " << message << "\n";
}
private:
std::ofstream logfile;
};
// 使用示例
logger logger("app.log");
logger.log("系统启动");
logger.log("用户登录: id=1001");
到此这篇关于c++实现文本与二进制文件读写操作的示例的文章就介绍到这了,更多相关c++ 文本与二进制文件读写操作内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论