C++ 文件操作详解
- [一、C++ 文件操作详解](#一、C++ 文件操作详解)
-
- 1、核心类
- 2、文件打开模式 (Open Modes)
- 3、基本操作流程
- 4、错误处理
- [5、 示例代码](#5、 示例代码)
- 6、重要提示
- 二、示例

一、C++ 文件操作详解
C++ 主要通过 <fstream> 头文件中定义的流类来进行文件操作。这些类继承自 <iostream> 中的标准输入输出流类,因此其使用方式与 cin、cout 非常相似。
1、核心类
std::ofstream(输出文件流): 用于向文件写入数据。std::ifstream(输入文件流): 用于从文件读取数据。std::fstream(文件流): 可以同时进行读写操作(取决于打开方式)。
2、文件打开模式 (Open Modes)
打开文件时,可以指定文件的操作模式。这些模式是位掩码常量,定义在 std::ios_base 命名空间中,通常使用 std::ios 作为别名。常用模式有:
std::ios::in: 以读取方式打开(ifstream默认)。std::ios::out: 以写入方式打开,会覆盖原有内容(ofstream默认)。std::ios::app: 以追加方式打开,所有写入都追加到文件末尾。std::ios::ate: 打开文件后,立即定位到文件末尾。std::ios::trunc: 如果文件存在,先将其内容清空(out模式默认包含)。std::ios::binary: 以二进制模式打开文件(默认是文本模式)。
模式可以组合使用,例如:
cpp
std::fstream file("data.txt", std::ios::in | std::ios::out); // 读写模式
std::ofstream outfile("log.txt", std::ios::app); // 追加模式
3、基本操作流程
-
打开文件:
- 在创建流对象时通过构造函数指定文件名和模式。
cppstd::ofstream outfile("output.txt"); // 默认 out + trunc std::ifstream infile("input.txt"); // 默认 in- 或者先创建对象,再调用
open()方法。
cppstd::fstream file; file.open("data.dat", std::ios::in | std::ios::out | std::ios::binary); -
检查文件是否成功打开:
在尝试读写之前,务必检查文件是否成功打开。
cppif (!outfile.is_open()) { // 或者 if (!outfile) std::cerr << "打开文件失败!" << std::endl; // 处理错误 return; } -
读写文件:
-
文本文件: 使用
<<(输出流) 和>>(输入流) 运算符,或者get()、getline()、put()等成员函数,就像操作cout和cin一样。cpp// 写入文本 outfile << "姓名: " << name << std::endl; outfile << "年龄: " << age << std::endl; // 读取文本 std::string line; while (std::getline(infile, line)) { // 逐行读取 std::cout << line << std::endl; } int value; infile >> value; // 读取一个整数 -
二进制文件: 使用
read()和write()成员函数。它们直接操作内存块。cpp// 写入二进制数据 (例如一个结构体) struct Person { char name[50]; int age; } p = {"张三", 30}; outfile.write(reinterpret_cast<char*>(&p), sizeof(p)); // 读取二进制数据 Person p_read; infile.read(reinterpret_cast<char*>(&p_read), sizeof(p_read));注意: 二进制模式读写不进行任何格式转换(如换行符转换),直接读写字节。
reinterpret_cast<char*>用于将对象指针转换为char*指针,因为read/write操作的是字节 (char)。
-
-
文件定位:
tellg(): 返回输入流的当前位置指针(读位置)。tellp(): 返回输出流的当前位置指针(写位置)。seekg(offset, direction): 设置输入流的位置指针。seekp(offset, direction): 设置输出流的位置指针。
方向 (direction):std::ios::beg: 文件开头 (默认)。std::ios::cur: 当前位置。std::ios::end: 文件末尾。
cppinfile.seekg(0, std::ios::end); // 定位到文件末尾 std::streampos size = infile.tellg(); // 获取文件大小 infile.seekg(0, std::ios::beg); // 重新定位到开头 -
关闭文件:
当流对象离开其作用域时,析构函数会自动关闭文件。但显式关闭是一个好习惯,特别是需要立即释放资源或重新打开文件时。
cppoutfile.close(); infile.close();
4、错误处理
除了检查 is_open(),还可以使用以下方法检查流状态:
good(): 流状态正常 (无错误)。eof(): 到达文件末尾。fail(): 发生非致命错误(可恢复,如格式错误)。bad(): 发生致命错误(流可能损坏)。
通常:
cpp
if (infile.fail() && !infile.eof()) {
// 处理读取错误 (非EOF导致)
}
// 或者
while (infile >> data) { // 操作成功且未到EOF时,条件为true
// 处理数据
}
5、 示例代码
- 写入文本文件:
cpp
#include <iostream>
#include <fstream>
int main() {
std::ofstream outfile("example.txt");
if (!outfile) {
std::cerr << "创建文件失败!" << std::endl;
return 1;
}
outfile << "Hello, File World!\n";
outfile << "This is a line of text.\n";
outfile << 42 << " " << 3.14159 << std::endl;
outfile.close();
return 0;
}
运行:

- 读取文本文件:
cpp
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ifstream infile("example.txt");
if (!infile) {
std::cerr << "打开文件失败!" << std::endl;
return 1;
}
std::string line;
while (std::getline(infile, line)) {
std::cout << line << std::endl;
}
infile.close();
return 0;
}
运行:

- 读写二进制文件:
cpp
#include <iostream>
#include <fstream>
struct Point {
double x, y;
};
int main() {
// 写入二进制
Point p1 = {1.0, 2.0}, p2 = {3.0, 4.0};
std::ofstream outbin("points.dat", std::ios::binary);
if (!outbin) return 1;
outbin.write(reinterpret_cast<char*>(&p1), sizeof(Point));
outbin.write(reinterpret_cast<char*>(&p2), sizeof(Point));
outbin.close();
// 读取二进制
Point p_read;
std::ifstream inbin("points.dat", std::ios::binary);
if (!inbin) return 1;
inbin.read(reinterpret_cast<char*>(&p_read), sizeof(Point));
std::cout << "Point1: (" << p_read.x << ", " << p_read.y << ")\n";
inbin.read(reinterpret_cast<char*>(&p_read), sizeof(Point));
std::cout << "Point2: (" << p_read.x << ", " << p_read.y << ")\n";
inbin.close();
return 0;
}
运行:

6、重要提示
- 文件路径: 可以使用相对路径或绝对路径。相对路径是相对于程序运行时的当前工作目录。
- 资源管理: 确保文件在不再需要时被关闭。利用 RAII (Resource Acquisition Is Initialization) 原则,让流对象的析构函数自动关闭文件是最安全的方式。
- 二进制模式: 处理非文本数据(如图像、结构体)时,必须 使用
std::ios::binary模式,否则可能发生意外的字符转换(如换行符\n在某些系统上可能被转换为\r\n)。 - 错误检查: 文件操作失败很常见(如文件不存在、权限不足、磁盘满)。务必在关键操作后进行错误检查。
掌握这些核心概念和操作,就能在 C++ 程序中有效地进行文件读写。
二、示例
以下是一个使用C++进行文件操作的示例代码,包含文件写入和读取的基本操作:
cpp
#include <iostream>
#include <fstream>
#include <string>
int main() {
// 文件写入操作
std::ofstream outFile("example.txt"); // 创建输出文件流
if (outFile.is_open()) {
outFile << "Hello, File I/O!\n";
outFile << "This is a sample text.\n";
outFile << "3.1415926535\n"; // 写入数字
outFile.close();
std::cout << "数据写入成功!" << std::endl;
} else {
std::cerr << "无法打开文件进行写入!" << std::endl;
}
// 文件读取操作
std::ifstream inFile("example.txt"); // 创建输入文件流
std::string line;
if (inFile.is_open()) {
std::cout << "\n文件内容:" << std::endl;
while (std::getline(inFile, line)) {
std::cout << line << std::endl;
}
inFile.close();
} else {
std::cerr << "无法打开文件进行读取!" << std::endl;
}
// 追加模式写入
std::ofstream appFile("example.txt", std::ios::app);
if (appFile.is_open()) {
appFile << "--- 追加内容 ---\n";
appFile.close();
std::cout << "\n追加内容成功!" << std::endl;
}
return 0;
}
代码说明:
-
文件写入:
- 使用
std::ofstream创建输出文件流 is_open()检查文件是否成功打开- 使用
<<运算符写入文本内容 - 操作完成后调用
close()关闭文件
- 使用
-
文件读取:
- 使用
std::ifstream创建输入文件流 std::getline()逐行读取内容- 将读取内容输出到控制台
- 使用
-
追加模式:
- 通过
std::ios::app标志以追加模式打开文件 - 新内容将添加到文件末尾而不覆盖原有内容
- 通过
运行结果:
数据写入成功!
文件内容:
Hello, File I/O!
This is a sample text.
3.1415926535
追加内容成功!


注意事项:
- 文件路径可以是相对路径(如示例)或绝对路径
- 操作前需确保有文件读写权限
- 使用
try-catch可增强异常处理能力 - 对于二进制文件操作,需使用
std::ios::binary模式
