C++ (fstream、istream、ostream) 文件读写操作分析
最近正再一次学习C++,因此记录一些学习过程的总结。
1 2 3 4 5 | // #include <fstream> //既有读也有写 ifstream //读 文件读操作,存储设备读区到内存中 ofstream //写 文件写操作 内存写入存储设备 //ifstream:定义要用于从文件中按顺序读取单字节字符数据的流. |
(一)、打开文件
打开文件的方法有两种:
1、在声名时,利用添加的文件名打开文件。
1 2 | fstream _file("text.txt");//这行语句会打开文件 fstream _file1;//这行不会打开任何文件 |
2、在fstream类中,成员函数open()实现打开文件的操作,从而将数据流和文件进行关联,通过ofstream,ifstream,fstream对象进行对文件的读写操作。
实际上,第一种方法即在声名时调用了open()方法
源码如下
(二)open()函数
源码:
__s:是文件名
__mode是打开文件的模式
文件名可以是绝对路径也可以是相对路径
相对路径的话即在该cpp文件所在的目录下的某文件。
绝对路径即是特指位置的文件。
mode有很多种方式:
如:
ios::in 为输入(读)而打开文件
ios::out 为输出(写)而打开文件
ios::ate 初始位置:文件尾
ios::app 所有输出附加在文件末尾
ios::trunc 如果文件已存在则先删除该文件
ios::binary 二进制方式
上述方式可以自行组合,利用或运算分割
例如:以二进制,即读取也写入的方式 打开相对路径下的文件text.txt
1 2 | //以二进制,即读取也写入的方式 打开相对路径下的文件text.txt fstream _file("text.txt",ios::in | ios::out | ios::binary); |
函数is_open()用于判读该文件是否打开,比较简单,不做赘述。
(三)close() 关闭文件
当文件读写操作完成之后,必须将文件关闭以使文件重新变为可访问的。
fstream成员函数close(),它负责将缓存中的数据排放出来并关闭文件。这个函数一旦被调用,原先的流对象就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程所访问了。
源码:
为防止流对象被销毁时还联系着打开的文件,析构函数将会自动调用关闭函数close。
源码
(四)文件的读写
文件的读:
利用字符数组做buff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //以二进制,即读取也写入的方式 打开相对路径下的文件text.txt #include <fstream> #include <iostream> using namespace std; int main(){<!-- --> char buff[256]; fstream _file("text.txt"); if(_file.is_open()){<!-- --> while( !_file.eof()){<!-- --> _file.getline(buff,200); cout<<buff<<endl; } }else{<!-- --> perror("error in file"); } _file.close(); system("pause"); return 0; } |
输出:
文件的写:
1.使用 write() 函数
第一个参数是要写入的数据,第二个参数是数据的大小。
1 2 3 4 5 6 7 8 9 10 | #include <fstream> #include <iostream> using namespace std; int main(){<!-- --> fstream _file("text.txt"); _file.write("aaaaaaaaaaaaaa",14); _file.close(); system("pause"); return 0; } |
结果:
源码:
2.使用重载<< >>
输出:
注意:这里在用open打开时,添加ios::app模式,会将输出到文件的数据以追加方式输出到该文件。不加app模式会直接覆盖原文件数据输出。
输出:
(五)状态标志符
一些验证文件流的状态的成员函数(所有都返回bool型返回值):
bad()
如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。
fail()
除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。
eof()
如果读文件到达文件末尾,返回true。
good()
这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。
要想重置以上成员函数所检查的状态标志,可以使用成员函数clear()。
(六)文件流的指针操作
tellg() 和 tellp()
这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前get 流指针的位置 (用tellg) 或 put 流指针的位置(用tellp).
源码:可以进去看看混个脸熟
tellg()函数不需要带参数,它返回当前定位指针的位置,也代表着输入流的大小。
seekg() 和seekp()
这对函数分别用来改变流指针get 和put的位置。两个函数都被重载为两种不同的原型:
seekg ( pos_type position );
seekp ( pos_type position );
使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。
seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );
使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:
ios::beg 从流开始位置计算的位移
ios::cur 从流指针当前位置开始计算的位移
ios::end 从流末尾处开始计算的位移
流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <fstream> #include <iostream> using namespace std; int main(){<!-- --> long st=0,end=0; fstream _file("text.txt"); st=_file.tellg(); _file.seekg(0,ios::end); end=_file.tellg(); _file.close(); cout<<"the file's size is "<<(end-st)<<endl; system("pause"); return 0; } |
以上是基本的文件流操作