文件操作
问题1 std::ios::in为什么是读取文件
在使用C++操作文件时经常遇到需要对文件进行读写操作,但是有个比较有意思的现象就是读取文件内容使用std::ios::in,向文件写入时设置的std::ios::out,再看下注释:
/// Perform input and output in binary mode (as opposed to text mode).
/// This is probably not what you think it is; see
/// https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.binary
static const openmode binary = _S_bin;
/// Open for input. Default for @c ifstream and fstream.
static const openmode in = _S_in;
/// Open for output. Default for @c ofstream and fstream.
static const openmode out = _S_out;
in注释的事 Open for input,很多同学读到这里就怀疑自己学的英语是不是写错了,这里命名写的是input为啥是读取文件???
如果你也有这个疑惑,那说明你把作用对象搞混了,这里的input相对于ifstream 或者fstream来说的,向ifstream input数据,可不就是从文件中读取数据吗。
问题2 std::ios::in在使用ifstream的时候是否多余
在打开文件时,我们常用这样的方式打开文件std::ifstream file(filename, std::ios::binary | std::ios::in);
,其实这里的std::ios::in写上就是良好的编程习惯,就算你不写ifstream构造函数中也是会默认添加上的。
如果有源码直接查看stl官方源码的注释也能看到这样的注释 Open for input. Default for @c ifstream and fstream.
,说明在ifstream对象或者fstream中,默认就是设置了std::ios::in的
示例代码
#include <iostream>
#include <fstream>
#include <cstdint> // for uint32_t
int main() {
const char* filename = "example.txt"; // 文件名
std::ifstream file(filename, std::ios::binary | std::ios::ate); // 打开文件,ate模式将文件指针移动到文件末尾
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filename << std::endl;
return 1; // 返回错误码
}
// 获取文件大小
uint32_t fileSize = static_cast<uint32_t>(file.tellg());
std::cout << "文件大小为: " << fileSize << " 字节" << std::endl;
// 假设你想从第100个字节开始读取50个字节的内容
const uint32_t offset = 100; // 起始偏移量
const uint32_t length = 50; // 需要读取的长度
// 将文件指针移动到指定的位置
file.seekg(offset, std::ios::beg);
// 检查是否成功移动
if (file.fail()) {
std::cerr << "无法将文件指针移动到指定位置." << std::endl;
file.clear(); // 清除状态标志
file.seekg(0, std::ios::beg); // 移动回文件开头
return 1;
}
// 准备一个缓冲区用来存储读取的数据
char buffer[length];
file.read(buffer, length);
// 检查是否成功读取数据
if (file.gcount() != length) { // gcount()返回实际读取的字节数
std::cerr << "无法读取指定长度的数据." << std::endl;
file.clear(); // 清除状态标志
file.seekg(0, std::ios::beg); // 移动回文件开头
return 1;
}
// 输出读取的数据
std::cout << "读取的数据: ";
for (uint32_t i = 0; i < length; ++i) {
std::cout << buffer[i];
}
std::cout << std::endl;
// 关闭文件
file.close();
return 0;
}