《C++ 文件操作》

一、基础概念:文件流与头文件

1.文件流类

ofstream:输出文件流(写入文件)。
ifstream:输入文件流(读取文件)。
fstream:输入/输出文件流(可读写文件)。
头文件:必须包含 <fstream>(文件操作)和 <iostream>(输入/输出基础)。

  其中ofstream中的o指的是out(输出),指的是数据流输出到文件,因此对于文件来说是写入的意思。ifstream同理。

 

二、文件操作基本流程

1. 打开文件

构造函数打开:

std::ofstream outFile("data.txt"); // 写入模式,文件不存在则创建
std::ifstream inFile("data.txt");  // 读取模式,文件不存在则失败

open()方式打开:

std::fstream file;
file.open("data.txt", std::ios::in | std::ios::out); // 读写模式

打开模式

std::ios::in    读取模式(ifstream 默认)
std::ios::out    写入模式(ofstream 默认,覆盖原有内容)
std::ios::app    追加模式(写入时在文件末尾添加)
std::ios::binary    二进制模式(避免文本转换,如换行符处理)
std::ios::trunc    截断模式(默认与 out 一起使用,清空文件)

  备注:std::ios::out的时候,默认隐式触发trunc,也就是只要使用out就会清空文件内容。除非std::ios::out | std::ios::app,才不会清空,会在文件末追加内容。

2. 检查文件是否成功打开

使用is_open():

if (!outFile.is_open()) {
    std::cerr << "Failed to open file!" << std::endl;
    return 1;
}

3. 关闭文件

显式调用 close() 或依赖析构函数自动关闭:

outFile.close(); // 显式关闭
// 或依赖 RAII:文件流对象离开作用域时自动关闭

 

三、文件读写

1. 写入文本文件(ofstream

格式化写入:使用 << 运算符(类似 cout):

std::ofstream outFile("text_data.txt");
outFile << "Hello, " << 42 << " " << 3.14 << std::endl;

写入多行:结合 std::endl 或 '\n'

outFile << "Line 1\nLine 2\n"; // 显式换行符

 

2. 读取文本文件(ifstream

逐行读取:使用 std::getline()

std::ifstream inFile("text_data.txt");
std::string line;
while (std::getline(inFile, line)) {
    std::cout << line << std::endl; // 输出每行内容
}

逐词读取:使用 >> 运算符(默认以空格分隔):

std::string word;
while (inFile >> word) {
    std::cout << word << " "; // 输出每个单词
}

 

3.写入二进制数据(ofstream + write()

使用 write() 方法直接写入字节:

struct Data {
    int id;
    double value;
};
Data data = {1, 3.14};
std::ofstream outFile("binary_data.bin", std::ios::binary);
outFile.write(reinterpret_cast<char*>(&data), sizeof(data));

关键点:

  • reinterpret_cast<char*> 将结构体指针转换为字节指针。
  • sizeof(data) 指定写入的字节数。

4.读取二进制数据(ifstream + read()

使用 read() 方法直接读取字节:

Data readData;
std::ifstream inFile("binary_data.bin", std::ios::binary);
inFile.read(reinterpret_cast<char*>(&readData), sizeof(readData));
std::cout << readData.id << ", " << readData.value << std::endl;

注意事项:

  • 二进制文件需严格匹配写入和读取的数据结构(如 struct 布局)。
  • 跨平台时需考虑字节序(大端/小端)问题。

 

四、文件流状态管理

good()    流处于正常状态(可读写)。
eof()    到达文件末尾(End Of File)。
fail()    操作失败(如类型不匹配、文件无法打开)。
bad()    严重错误(如磁盘损坏、流被破坏)。

eg:

if (inFile.fail()) {
    std::cerr << "Read operation failed!" << std::endl;
}

重置状态标志:

inFile.clear(); // 清除所有错误标志

五、文件指针操作(随机访问)

1. 移动指针

seekg()(输入流)和 seekp()(输出流):

std::fstream file("data.bin", std::ios::in | std::ios::out | std::ios::binary);
file.seekg(10, std::ios::beg); // 从文件开头移动 10 字节
file.seekp(0, std::ios::end); // 移动到文件末尾(追加写入)
  • seekg(seek get):用于移动输入流(读取位置)的指针。
  • seekp(seek put):用于移动输出流(写入位置)的指针。

偏移量模式:

std::ios::beg    从文件开头计算偏移量。
std::ios::cur    从当前指针位置计算偏移量。
std::ios::end    从文件末尾计算偏移量。

 

2. 获取当前指针位置

tellg() 和 tellp()

std::streampos pos = file.tellg(); // 获取当前读取位置
std::cout << "Current position: " << pos << std::endl;

 

六、文件异常处理

使用 try-catch 捕获文件操作异常:

try {
    std::ifstream inFile("missing_file.txt");
    if (!inFile) {
        throw std::runtime_error("File not found!");
    }
} catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
}

 

posted @ 2025-08-25 15:36  一个不知道干嘛的小萌新  阅读(103)  评论(0)    收藏  举报