文件流
myfstreamfstream Testmyfstreamfstream流对象的定义流对象关联文件open 函数打开方式关闭流对象文件读写读写文本文件读写接口读一字/行一次读取一个字符一次读写一行读写二进制文件读写接口读写结构体随机文件读写与文件指针相关的函数参照位置代码示例myfstream
fstream Test
#include <iostream>#include <fstream>using namespace std;int main(){fstream fs("bbb.txt", ios::in | ios::out | ios::trunc);if(!fs)cout << "open error" << endl;fs.put('a');fs.put('b');fs.put('c');fs.put('d');fs.seekp(0, ios::beg);char ch;while (fs.get(ch),!fs.eof()){cout << ch;}fs.close();return 0;}
运行结果为:
myfstream
自实现对 FILE*fp 的包装,实现对象对文件的访问。实现成员函数 put/get 函数。
自实现封装的时候最核心的是句柄,在这里核心句柄就是FILE * pf 读者可以自行模仿上面代码进行实现。
fstream
对文件的操作是由文件流类完成的。文件流类在流与文件间建立连接。由于文件流分为三种:文件输入流、文件输出流、文件输入/输出流,所以相应的必须将文件流说明为ifstream、ofstream 和 fstream 类的对象,然后利用文件流的对象对文件进行操作。
对文件的操作过程可按照以下四步进行:即定义文件流类的对象、打开文件、对文件进行读写操作、关闭文件,下面分别进行说明。
流对象的定义
//流类 流对象;ifstream ifile; //定义一个文件输入流对象ofstream ofile; //定义一个文件输出流对象fstream iofile; //定义一个文件输出/输入流对象
一般情况下在定义对象的时候指定文件和权限,也有一种或情况不指定文件和权限:
#include <iostream>#include <fstream>using namespace std;int main(){fstream fs;fs.open("abc.txt", ios::in | ios::out | ios::trunc);if(!fs)cout << "open error" << endl;return 0;}
那么为什么不使用open函数的返回值呢?
流对象关联文件
open 函数
定义了文件流对象后,就可以利用其成员函数 open()打开需要操作的文件,该成员函数的函数原型为:
void open(const unsigned char *filename,int mode,int access=filebuf:openprot);
其中:filename 是一个字符型指针,指定了要打开的文件名;mode 指定了文件的打开方式,其值如下表所示;access 指定了文件的系统属性,取默认即可。并且open函数返回值为void类型,所以不能使用open函数的返回值进行判断。
打开方式
几点说明:
① 在实际使用过程中,可以根据需要将以上打开文件的方式用"|" 组合起来。如:
ios::in|ios::out
表示以读/写方式打开文件
ios::in|ios:: binary
表示以二进制读方式打开文件
ios::out|ios:: binary
表示以二进制写方式打开文件
ios::in|ios::out|ios::binary
表示以二进制读/写方式打开文件
② 如果未指明以二进制方式打开文件,则默认是以文本方式打开文件。
③ 构造函数打开文件
对于 ifstream 流, mode 参数的默认值为 ios::in,
对于 ofstream 流,mode 的默 认值为 ios::out|ios::trunc,
对于 fstream 流, mode 的默认值为 ios::int|ios::out|ios::app
④ ios::int|ios::out 是什么?
是命名空间的 ios 中一堆枚举。
关闭流对象
在文件操作结束(即读、写完毕)时应及时调用成员函数 close()来关闭文件。该函数比较简单,没有参数和返回值。
#include <iostream>#include <fstream>using namespace std;int main(){fstream fs;fs.open("abc.txt", ios::in | ios::out | ios::trunc);if(!fs)cout << "open error" << endl;fs.close(); //关闭流对象return 0;}
文件读写
读写文本文件
读写接口
读一字/行
一次读取一个字符
#include <iostream>#include <fstream>using namespace std;int main(){fstream fs;fs.open("abc.txt", ios::in | ios::out | ios::trunc);if(!fs)cout << "open error" << endl;for (char i = 'a'; i < 'z'; i++)fs.put(i);fs.seekp(0, ios::beg);char ch;while (fs.get(ch))cout << ch << endl;fs.close();return 0;}
运行结果为:
#include <iostream>#include <fstream>using namespace std;int main(){fstream fs;fs.open("abc.txt", ios::in | ios::out | ios::trunc);if(!fs)cout << "open error" << endl;for (char i = 'a'; i < 'z'; i++)fs << i;fs.seekp(0, ios::beg);char ch;while (fs>>ch)cout << ch << endl;fs.close();return 0;}
运行结果为:
一次读写一行
#include <iostream>#include <fstream>using namespace std;int main(){fstream fs;fs.open("abc.txt", ios::in | ios::out | ios::trunc);if(!fs)cout << "open error" << endl;fs << "aaaaaaaaaaa" << endl;fs << "bbbbbbbbbbb" << endl;fs << "ccccccccccc" << endl;fs.seekp(0, ios::beg);char buf[1024];while (fs>>buf)cout << buf << endl;fs.close();return 0;}
运行结果为:
上面一次读取一行的用法有缺陷,如果超过1024个,程序就会崩溃。
读写二进制文件
读写接口
读写结构体
#include <iostream>#include <fstream>using namespace std;struct Student{char name[100];int num;int age;char sex;};int main(){fstream fs;fs.open("add.txt", ios::in | ios::out | ios::trunc | ios::binary);if (!fs)cout << "open error" << endl;Student s[3] = {{"li",1001,18,'f'},{"Fun",1002,19,'m'},{"Wang",1004,17,'f'}};fs.write((char*)&s, sizeof(s));fs.seekg(0, ios::beg);Student ss;while (fs.read((char*)&ss, sizeof(Student)), !fs.eof()){cout << "Name " << ss.name << endl;cout << "Num " << ss.num << endl;cout << "Age " << ss.age << endl;cout << "Sex " << ss.sex << endl;cout << "---------------" << endl;}return 0;}
运行结果为:
随机文件读写
与文件指针相关的函数
g 代表 get 的意思用于输入的函数。p 代表 put 的意思,用于输出函数。如果既是可输
入又是可输出的文件,则任意使用。
参照位置
代码示例
//输入文件中的指针向前移到 100 个字节的位置infile.seekg(100); //输入文件中的指针从当前位置后移 50 个字节infile.seekg(-50,ios::cur); //输出文件中指针从文件尾后移 75 个字节outfile.seekp(-75,iso::end);