概述
定义:
文件流是 C++ 中用于处理文件输入 / 输出(I/O)操作的一种抽象概念。它将文件视为字节序列的源(输入)或目标(输出),并提供了一系列的方法来读取和写入这些字节。文件流可以看作是连接程序和外部文件的通道,通过这个通道,程序可以从文件中获取数据(类似于从文件这个 “数据源” 中 “抽取” 数据),或者将数据存储到文件中(类似于将数据 “注入” 到文件这个 “存储库”)。
类型:
类型 | 功能 |
输入文件流:ifstream | 读数据 |
输出文件流:ofstream | 写数据 |
文件流:fstream | 读写数据 |
函数
基础函数
// 输出文件流(打开文件写入)
ofstream outFile(fileName, ios::app);//以追加写入方式
ofstream outFile(fileName, ios::out);//清空文件再写入
ofstream outFile(fileName, ios::out|ios::binary);//清空文件再写入(以二进制写入)
//输入文件流(打开文件读取)
ifstream inFile;
inFile.open("文件名");//打开文件
//读取或写入方式
file.get(char);//读取一个字符到char中
getline(inFile, tempString);//读取一行到char中
//其他函数
file.open("文件名");//打开文件
file.close();//关闭文件
file.is_open()//判断文件是否被打开
file.eof()//检查是否已经到达文件末尾,若到达则返回1
输入文件流的常用函数
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
int main() {
std::ifstream file;
// 1. 打开文件
file.open("example.txt", std::ios::in);
if (!file.is_open()) {
std::cerr << "无法打开文件 example.txt" << std::endl;
return 1;
}
// 2. 读取一个字符
char firstChar = file.get();
std::cout << "读取的第一个字符是: " << firstChar << std::endl;
// 3. 忽略接下来的 5 个字符
file.ignore(5);
std::cout << "忽略了接下来的 5 个字符" << std::endl;
// 4. 查看下一个字符但不读取
char nextChar = file.peek();
std::cout << "下一个字符是: " << nextChar << std::endl;
// 5. 读取一行数据
char buffer[100];
file.getline(buffer, 100);
std::cout << "读取的一行数据是: " << buffer << std::endl;
// 6. 读取 20 个字节的数据
char data[20];
file.read(data, 20);
std::cout << "读取的 20 个字节数据是: " << data << std::endl;
// 7. 输出当前读取位置
std::streampos currentPos = file.tellg();
std::cout << "当前读取位置: " << currentPos << std::endl;
// 8. 将读取位置向前移动 10 个字节
file.seekg(-10, std::ios::cur);
std::cout << "将读取位置向前移动 10 个字节" << std::endl;
// 9. 再次读取一个字符
char anotherChar = file.get();
std::cout << "移动位置后读取的字符是: " << anotherChar << std::endl;
// 10. 检查是否到达文件末尾
if (file.eof()) {
std::cout << "已到达文件末尾" << std::endl;
} else {
std::cout << "未到达文件末尾" << std::endl;
}
// 11. 检查文件流状态是否正常
if (file.good()) {
std::cout << "文件流状态正常" << std::endl;
} else {
std::cout << "文件流状态异常" << std::endl;
}
// 12. 检查是否发生读取失败或其他错误
if (file.fail()) {
std::cerr << "读取失败或其他错误发生" << std::endl;
}
// 13. 检查是否发生严重错误
if (file.bad()) {
std::cerr << "发生严重错误" << std::endl;
}
// 14. 清除文件流状态标志
file.clear();
std::cout << "清除文件流状态标志" << std::endl;
// 15. 关闭文件
file.close();
return 0;
}
输出文件流的常用函数
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ofstream file;
// 1. 打开文件
file.open("output.txt", std::ios::out | std::ios::app);
if (!file.is_open()) {
std::cerr << "无法打开文件 output.txt" << std::endl;
return 1;
}
// 2. 写入一个字符
char ch = 'A';
file.put(ch);
std::cout << "写入一个字符: " << ch << std::endl;
// 3. 写入一个字符串
std::string str = "Hello, World!";
file.write(str.c_str(), str.length());
std::cout << "写入一个字符串: " << str << std::endl;
// 4. 刷新文件缓冲区
file.flush();
std::cout << "刷新文件缓冲区" << std::endl;
// 5. 输出当前写入位置
std::streampos currentPos = file.tellp();
std::cout << "当前写入位置: " << currentPos << std::endl;
// 6. 将写入位置向后移动 5 个字节
file.seekp(5, std::ios::cur);
std::cout << "将写入位置向后移动 5 个字节" << std::endl;
// 7. 再次写入一个字符
char anotherChar = 'B';
file.put(anotherChar);
std::cout << "移动位置后写入的字符是: " << anotherChar << std::endl;
// 8. 检查文件流状态是否正常
if (file.good()) {
std::cout << "文件流状态正常" << std::endl;
} else {
std::cout << "文件流状态异常" << std::endl;
}
// 9. 检查是否发生写入失败或其他错误
if (file.fail()) {
std::cerr << "写入失败或其他错误发生" << std::endl;
}
// 10. 检查是否发生严重错误
if (file.bad()) {
std::cerr << "发生严重错误" << std::endl;
}
// 11. 清除文件流状态标志
file.clear();
std::cout << "清除文件流状态标志" << std::endl;
// 12. 关闭文件
file.close();
return 0;
}
例子
1.打开文件读取并打印
string tempchars;
ifstream ifsProgream;
ifsProgream.open("F:/caozuoxitong/chuliqidiaodu/document/progream.txt");
while (ifsProgream >> tempchars)
{
cout << tempchars << endl;
}
2.返回
vector<unsigned char> FileModule::ReadFileBinary(string FileName)
{
vector<unsigned char> buffer;
ifstream inFile(FileName,ios::binary);
if(!inFile.is_open())
{
cout << "打开文件失败" << endl;
return buffer;
}
else
{ //获取文件大小
streampos fileSize =GetFileSize(FileName);
buffer.resize(fileSize);
inFile.read(reinterpret_cast<char *>(buffer.data()),fileSize);
inFile.close();
}
return buffer;
}
输入输出文件流常用函数
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
int main() {
std::fstream inFile;
std::fstream outFile;
// 1. 打开输入文件
inFile.open("input.txt", std::ios::in);
if (!inFile.is_open()) {
std::cerr << "无法打开输入文件 input.txt" << std::endl;
return 1;
}
// 2. 打开输出文件
outFile.open("output.txt", std::ios::out | std::ios::trunc);
if (!outFile.is_open()) {
std::cerr << "无法打开输出文件 output.txt" << std::endl;
inFile.close();
return 1;
}
// 3. 读取一行数据
char buffer[100];
inFile.getline(buffer, 100);
std::cout << "从输入文件读取的一行数据是: " << buffer << std::endl;
// 4. 对读取的数据进行处理,例如将字符全部转换为大写
for (int i = 0; i < strlen(buffer); ++i) {
if (buffer[i] >= 'a' && buffer[i] <= 'z') {
buffer[i] = buffer[i] - 'a' + 'A';
}
}
std::cout << "处理后的数据是: " << buffer << std::endl;
// 5. 将处理后的数据写入输出文件
outFile.write(buffer, strlen(buffer));
std::cout << "将处理后的数据写入输出文件" << std::endl;
// 6. 检查输入文件是否到达末尾
if (inFile.eof()) {
std::cout << "输入文件已到达末尾" << std::endl;
}
// 7. 读取一个字符
char ch = inFile.get();
if (inFile.good()) {
std::cout << "从输入文件读取的一个字符是: " << ch << std::endl;
// 8. 将该字符写入输出文件
outFile.put(ch);
std::cout << "将该字符写入输出文件" << std::endl;
} else {
std::cerr << "读取字符时出现错误" << std::endl;
}
// 9. 移动输入文件指针
inFile.seekg(0, std::ios::beg);
std::cout << "将输入文件指针移到文件开头" << std::endl;
// 10. 读取一定数量的字节
char data[20];
inFile.read(data, 20);
std::cout << "从输入文件读取的 20 个字节的数据是: " << data << std::endl;
// 11. 将读取的数据再次写入输出文件
outFile.write(data, inFile.gcount());
std::cout << "将读取的 20 个字节的数据写入输出文件" << std::endl;
// 12. 检查输入文件流状态
if (inFile.good()) {
std::cout << "输入文件流状态正常" << std::endl;
} else if (inFile.eof()) {
std::cout << "输入文件已到达末尾" << std::endl;
} else if (inFile.fail()) {
std::cerr << "输入文件读取失败" << std::endl;
} else if (inFile.bad()) {
std::cerr << "输入文件发生严重错误" << std::endl;
}
// 13. 检查输出文件流状态
if (outFile.good()) {
std::cout << "输出文件流状态正常" << std::endl;
} else if (outFile.fail()) {
std::cerr << "输出文件写入失败" << std::endl;
} else if (outFile.bad()) {
std::cerr << "输出文件发生严重错误" << std::endl;
}
// 14. 刷新输出文件缓冲区
outFile.flush();
std::cout << "刷新输出文件缓冲区" << std::endl;
// 15. 关闭文件
inFile.close();
outFile.close();
return 0;
}
易错点
1.任何情况下的文件流语句都会生效,如:循环的条件判断中文件流会生效,见下图中的ifsProgream >> tempChars语句,若有两个并列条件时,最好把文件流语句放在后边,这样判断第一个条件失败后就会跳出循环,跳过后边的文件流语句。
while ( i<3&& ifsProgream >> tempChars)
{
tempCharss[i] = tempChars;
i++;
}
2.读取二进制文件只能使用unsigned char储存,否则会出错。
有符号字符(signed char
):
可以表示范围为 -128 到 127 的整数。如果存储的数据超出这个范围,会导致符号位的解释问题。例如,如果一个字节存储的值是 255(二进制 11111111
),在有符号字符中,它将被解释为 -1。
无符号字符(unsigned char
):
可以表示范围为 0 到 255 的整数,正好匹配一个字节的所有可能值。
二进制文件存储的是原始的字节数据,这些数据可以代表任何信息,包括但不限于文本、图像、音频、视频或自定义的二进制数据结构。每个字节的值范围是从 0 到 255(无符号)或 -128 到 127(有符号)。虽然二进制文件本身并不固有地是无符号的,但在存储和处理二进制文件的字节数据时,使用 unsigned char
是一种更安全、更准确和更通用的方法,因为它避免了符号位的解释问题,确保了数据的原始字节值的正确表示和处理。这有助于确保程序在不同平台上的一致性和正确性,尤其在处理图像、音频、视频和自定义二进制数据结构等应用中。