当前位置: 首页 > news >正文

c++文件操作详解

C++ 提供了强大的文件操作功能,主要通过 <fstream> 头文件中的类来实现。以下是对C++文件操作的全面解析:

一、文件流类体系

C++ 文件操作基于流的概念,核心类包括:

类名描述继承自
fstream文件流(读写操作)iostream
ifstream输入文件流(读操作)istream
ofstream输出文件流(写操作)ostream
filebuf文件缓冲区streambuf

二、文件打开模式

文件打开模式通过位掩码常量指定,可组合使用:

模式标志描述
ios::in打开文件进行读取(ifstream默认)
ios::out打开文件进行写入(ofstream默认),会截断现有文件
ios::app追加模式,所有写入操作都在文件末尾进行
ios::ate打开文件后定位到文件末尾
ios::trunc如果文件存在,则截断文件(out模式默认启用)
ios::binary以二进制模式打开文件(避免文本转换)
ios::nocreate如果文件不存在,打开失败(非标准,建议用C++17文件系统)
ios::noreplace如果文件存在,打开失败(非标准)

三、文件基本操作

1. 打开文件

#include <fstream>// 方式1:构造函数打开
std::ofstream outFile("output.txt", std::ios::out | std::ios::app);// 方式2:open()方法打开
std::ifstream inFile;
inFile.open("input.txt", std::ios::in);// 检查文件是否成功打开
if (!outFile.is_open()) {std::cerr << "Error opening file!" << std::endl;return 1;
}

2. 关闭文件

outFile.close();  // 显式关闭文件
inFile.close();   // 文件流析构时会自动关闭,但显式关闭是好习惯

3. 文件状态检查

if (inFile.fail()) {// 操作失败(如类型不匹配)
}if (inFile.bad()) {// 严重错误(如磁盘故障)
}if (inFile.eof()) {// 到达文件末尾
}if (inFile.good()) {// 一切正常
}// 重置错误状态
inFile.clear();

四、文本文件操作

1. 写入文本文件

std::ofstream textOut("data.txt");
if (textOut) {textOut << "Line 1: Hello, World!\n";textOut << "Line 2: The answer is " << 42 << "\n";textOut << "Line 3: Pi ≈ " << 3.14159 << "\n";
}

2. 读取文本文件

std::ifstream textIn("data.txt");
if (textIn) {// 逐行读取std::string line;while (std::getline(textIn, line)) {std::cout << line << std::endl;}// 重置文件指针到开头textIn.clear();textIn.seekg(0);// 按单词读取std::string word;while (textIn >> word) {std::cout << word << " ";}
}

五、二进制文件操作

1. 写入二进制数据

struct Record {int id;char name[50];double balance;
};Record records[3] = {{1, "Alice", 100.50},{2, "Bob", 250.75},{3, "Charlie", 500.25}
};std::ofstream binOut("data.bin", std::ios::binary);
if (binOut) {binOut.write(reinterpret_cast<char*>(records), sizeof(records));
}

2. 读取二进制数据

std::ifstream binIn("data.bin", std::ios::binary);
if (binIn) {// 获取文件大小binIn.seekg(0, std::ios::end);size_t fileSize = binIn.tellg();binIn.seekg(0, std::ios::beg);// 计算记录数量size_t numRecords = fileSize / sizeof(Record);Record* readRecords = new Record[numRecords];// 读取数据binIn.read(reinterpret_cast<char*>(readRecords), fileSize);// 处理数据...delete[] readRecords;
}

六、文件定位

std::fstream file("data.txt", std::ios::in | std::ios::out);if (file) {// 获取当前位置std::streampos pos = file.tellg();// 移动到文件开头file.seekg(0, std::ios::beg);// 移动到文件末尾file.seekg(0, std::ios::end);// 向前移动10字节file.seekg(10, std::ios::cur);// 向后移动5字节file.seekg(-5, std::ios::cur);// 移动到第100字节处file.seekg(100);
}

七、C++17 文件系统库

C++17 引入了 <filesystem> 头文件,提供了更高级的文件操作功能:

#include <filesystem>
namespace fs = std::filesystem;// 创建目录
fs::create_directory("data");// 复制文件
fs::copy_file("source.txt", "data/destination.txt");// 检查文件属性
if (fs::exists("data.txt")) {std::cout << "File size: " << fs::file_size("data.txt") << " bytes\n";std::cout << "Last modified: " << fs::last_write_time("data.txt") << "\n";
}// 遍历目录
for (const auto& entry : fs::directory_iterator(".")) {if (entry.is_regular_file()) {std::cout << "File: " << entry.path() << "\n";} else if (entry.is_directory()) {std::cout << "Directory: " << entry.path() << "\n";}
}// 删除文件
fs::remove("old_data.txt");// 递归删除目录
fs::remove_all("obsolete_data");

八、高级文件操作技巧

1. 内存映射文件(平台特定)

// Windows 示例
#include <windows.h>HANDLE hFile = CreateFile("large.bin", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
char* data = (char*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);// 使用 data 指针访问文件内容...UnmapViewOfFile(data);
CloseHandle(hMap);
CloseHandle(hFile);

2. 临时文件处理

#include <cstdio>// 创建临时文件
FILE* tmpFile = tmpfile();
if (tmpFile) {fputs("Temporary data", tmpFile);rewind(tmpFile);char buffer[256];fgets(buffer, sizeof(buffer), tmpFile);std::cout << "Temp content: " << buffer << std::endl;fclose(tmpFile); // 自动删除
}// 使用C++17文件系统
auto tempPath = fs::temp_directory_path() / "tempfile.tmp";
std::ofstream tempOut(tempPath);
// 使用临时文件...
fs::remove(tempPath); // 手动删除

九、错误处理与最佳实践

  1. 始终检查文件操作结果
if (!file) {// 处理错误}
  1. 使用RAII管理资源
{std::ofstream file("data.txt");// 使用文件...
} // 文件自动关闭
  1. 处理大文件
    #ifdef _WIN32// Windows 上处理大于2GB的文件std::ifstream bigFile("large.bin", std::ios::binary | std::ios::ate);bigFile.seekg(0, std::ios::beg);#endif
  1. 跨平台路径处理
// 使用C++17文件系统fs::path filePath = "data";filePath /= "subdir";filePath /= "file.txt";// 输出平台无关路径std::cout << "Path: " << filePath.generic_string() << std::endl;
  1. 异常处理
	std::ifstream file;file.exceptions(std::ifstream::failbit | std::ifstream::badbit);try {file.open("important.txt");// 文件操作...} catch (const std::ios_base::failure& e) {std::cerr << "File error: " << e.what() << std::endl;}

十、性能优化建议

  1. 使用缓冲区
char buffer[4096];std::ifstream inFile("large.bin", std::ios::binary);while (inFile.read(buffer, sizeof(buffer))) {// 处理缓冲区数据}
  1. 减少文件打开/关闭次数
    • 批量处理文件操作
    • 复用文件流对象
  2. 使用内存映射处理大文件
    • 避免多次读写操作
    • 提供随机访问能力
  3. 异步文件I/O
#include <future>auto readFuture = std::async(std::launch::async, []{std::ifstream file("data.bin", std::ios::binary);// 读取操作...});// 主线程继续执行其他任务...readFuture.get(); // 等待读取完成
  1. 选择合适的打开模式

    • 二进制模式避免文本转换开销
    • 追加模式减少文件定位开销

总结

C++提供了丰富的文件操作功能:

  • 基础文本和二进制文件读写
  • 文件定位和状态管理
  • C++17强大的文件系统库
  • 高级技术如内存映射和异步I/O
http://www.dtcms.com/a/298275.html

相关文章:

  • ubuntu安装cuda版本问题
  • 平时开发中使用 Redis 分布式锁,有哪些需要注意的问题?
  • Mysql 日志 binlog redolog
  • 基于springboot的剧本杀预约管理系统
  • Metaspace耗尽导致OOM问题
  • JAVA知识点(三):Spring与ORM框架
  • 【lucene】如何给StandardAnalyzer添加charfilter
  • HANA语法随手记:<> ‘NULL‘值问题
  • php算法-- 关联数组使用,优化sip账号去重
  • 验证 GitHub Pages 的自定义域(Windows)
  • 从混乱到秩序:IT服务管理如何重塑企业运营效率
  • CTF-Web题解:“require_once(‘flag.php‘); assert(“$i == $u“);”
  • C++ STL常用容器总结(vector, deque, list, map, set)
  • Schmidt 分解 ⚙️ 与 SVD 之间的本质联系
  • IDM:registered with a fake serial number
  • TDengine 转化函数 TO_UNIXTIMESTAMP 用户手册
  • 188.买卖股票的最佳时机IV 309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费
  • Java 笔记 lambda
  • 多层感知机(深度学习-李沐-学习笔记)
  • 【WPS】office邮件合并,怎么将数据源excel中的下一条拼接在文档中的下一个位置
  • selenium 元素定位
  • 深入浅出设计模式——创建型模式之工厂模式
  • 机器学习(九):KNN算法全解析与项目实践
  • 记录es收集日志报错问题as the final mapping would have more than 1 type[XXX,doc]
  • HCIP MGRE实验
  • 【机器学习之推荐算法】基于矩阵分解和损失函数梯度下降的协同过滤算法实现
  • RAG实战指南 Day 24:上下文构建与提示工程
  • C 语言 | 结构体详解:自定义数据类型的艺术
  • 【第四章:大模型(LLM)】01.神经网络中的 NLP-(1)RNN、LSTM 和 GRU 的基本原理和应用
  • MySQL常用日期函数总结