100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > (P60)io流类库:文件读写 二进制文件的读写 文件随机读写tellp tellg seekp seekg

(P60)io流类库:文件读写 二进制文件的读写 文件随机读写tellp tellg seekp seekg

时间:2019-06-27 17:17:18

相关推荐

(P60)io流类库:文件读写 二进制文件的读写 文件随机读写tellp tellg seekp seekg

文章目录

1.文件读写2.二进制文件的读写3.文件随机读写tellp、tellg、seekp、seekg

1.文件读写

文本读写方式1:<<, >>,

文本读写方式2:get, put,

read,

write

文本模式打开与二进制模式打开的区别

eg:P60\01.cpp

#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;int main(void){ofstream fout( "test.txt");fout << "abc" << " " << 200;//先把abc 200写入到文件中fout.close();ifstream fin( "test.txt");string s;int n;//fin>>n>>s;不按照顺序读取的话,会输出异常状态fin >> s >> n;//用文件输入流打开文件,并将其输出cout << s << " " << n << endl;return 0;}

测试:

eg:P60\02.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;int main(void){ofstream fout1( "test2.txt");assert(fout1);char ch;//往一个文件中写入26个字母for ( int i = 0; i < 26; i++){ch = 'A' + i;fout1.put(ch);}fout1.close();ifstream fin1( "test2.txt");//读取文件到结束时,文件流处于EOF状态,类型转换指针void*指针会返回空指针,就跳出循环了while (fin1.get(ch)){cout << ch;}cout << endl;return 0;}

测试:写入文件的结果

26个字节

eg:P60\03.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;int main(void){/*如果以文本方式打开文件,写入字符的时候,遇到\n会做转换,写入\r不做转换如果以二进制方式打开文件写入字符的时候,遇到\n不会做转换windows平台\n会转换为 \r\nlinux平台保留不变mac系统\n转换为\r *///默认以文本方式打开文件ofstream fout1( "test3.txt");fout1<<"ABC\r\n";fout1.close();return 0;}

测试:是6个字符,A,B,C,\r,\r,\n总共6个字符

eg:P60\04.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;int main(void){/*(1)如果以文本方式打开文件,写入字符的时候,遇到\n会做转换,写入\r不做转换windows平台\n会转换为 \r\nlinux平台保留不变mac系统\n转换为\r (2)如果以二进制方式打开文件写入字符的时候,遇到\n不会做转换(3)以文本方式打开文件,也可以写入二进制数据以二进制方式打开文件,也可以写入文本写入的数据是二进制还是文本,与打开方式无关,与写入使用的函数有关要写入二进制数据,应该用write,相应的读要用read*///以二进制方式打开ofstream fout1( "test3.txt", ios::out| ios::binary );fout1<<"ABC\r\n";fout1.close();return 0;}

测试:不做任何转换,输出5个字节

2.二进制文件的读写

二进制文件不同于文本文件,它可用于任何类型的文件(包括文本文件)

对二进制文件的读写可采取从istream类继承下来的成员函数read()和从ostream类继承下来的成员函数write()

文件打开操作时使用枚举常量ios::binary,eg:ofstream fout(“binary.dat”, ios::out|ios::binary);

eg:P60\05.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;struct Test{int a;int b;};//测试:以文本方式打开文件,也可以写入二进制数据//写入的数据是二进制还是文本,与打开方式无关,与写入使用的函数有关int main(void){Test test = {100, 200};//以文本方式打开ofstream fout("test4.txt");//以二进制方式写入8个字节(将100在机器中的内存表示写入文件中),转化成char*fout.write(reinterpret_cast<char*>(&test), sizeof(Test));fout.close();//如何知道写入成功?可以读取出来Test test2;ifstream fin("test4.txt");fin.read(reinterpret_cast<char*>(&test2), sizeof(Test));cout<<test2.a<<" "<<test2.b<<endl;return 0;}

测试

因为以文本方式打开是看不到这些字符的,因为它超过了ASCII码字符所表示的范围

eg:P60\07.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;struct Test{int a;int b;};//测试:以二进制方式打开文件,也可以写入文本int main(void){Test test = {100, 200};//以二进制方式打开ofstream fout("test4.txt", ios::out|ios::binary);//c插入运算符<<是以文本方式写入数据的//虽然以二进制方式打开,但是写入的方式是文本的方式fout<<"abc"<<200;return 0;}

测试:

P60\08.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;struct Test{int a;string b;//string对象string c;};//MyString类大小总是4字节,与字符串str无关//同样string只与其成员有关,他里面的成员就是一些指针,不同平台不一样,当前平台是32字节,其他平台可能是16字节,因为持有的数据成员不同class MyString{char* str;}int main(void){Test t1;t1.a = 100;t1.b = "xxxabcdddddddddddddddddddddddddddddddddddddddddddddddffffffffffffffffffffffffff";t1.c = "yyyffffffffffffffffffffffffffffffffddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";//下面的写入方式是不行的//因为每次写入的时候,并不是将字符串b和c的所有内容写入到文件中,总是写入了68字节而已(struct Test:4+32+32)//只是写将string中的成员指针写进去了,而没有将指针所指向的内存写入进去ofstream fout("test6.txt", ios::out|ios::binary);fout.write((char*)&t1, sizeof(t1));fout.close();ifstream fin("test6.txt", ios::out|ios:binary);Test t2;fin.read((char*)&t2, sizeof(Test));cout<<t2.a<<" "<<t2.b<<" "<<t2.c<<endl;fin.close();//string类型的大小总是32字节//计算一个类型或者说一个类型所对应对象的大小,与字符串内容无关cout<<sizeof(Test)<<endl;string a = "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";cout<<sizeof(string)<<endl;cout<<sizeof(a)<<endl;return 0;}

测试:

字符串超过32字节

写入的文件总是68字节

eg:P60\09.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;struct Test{int a;string b;//string对象string c;};//MyString类大小总是4字节,与字符串str无关//同样string只与其成员有关,他里面的成员就是一些指针,不同平台不一样,当前平台是32字节,其他平台可能是16字节,因为持有的数据成员不同class MyString{char* str;}int main(void){Test t1;t1.a = 100;t1.b = "xxxabcdddddddddddddddddddddddddddddddddddddddddddddddffffffffffffffffffffffffff";t1.c = "yyyffffffffffffffffffffffffffffffffddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";// //下面的写入方式是不行的// //因为每次写入的时候,并不是将字符串b和c的所有内容写入到文件中,总是写入了68字节而已(struct Test:4+32+32)// ofstream fout("test6.txt", ios::out|ios::binary);// fout.write((char*)&t1, sizeof(t1));// fout.close();// ifstream fin("test6.txt", ios::out|ios:binary);// Test t2;// fin.read((char*)&t2, sizeof(Test));// cout<<t2.a<<" "<<t2.b<<" "<<t2.c<<endl;// fin.close();// //string类型的大小总是32字节// //计算一个类型或者说一个类型所对应对象的大小,与字符串内容无关// cout<<sizeof(Test)<<endl;// string a = "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";// cout<<sizeof(string)<<endl;// cout<<sizeof(a)<<endl;//正确的写入方式:一个一个写入ofstream fout("test6.txt", ios::out|ios::binary);//写入字符串的时候,最好先写入字符串的长度,然后写入字符串实际数据fout.write((char*)&t1.a, sizeof(int));int len;len = t1.b.length();fout.write((char*)&len, sizeof(int));fout.write((char*)&t1.b.data(), t1.b.length());len = t1.c.length();fout.write((char*)&len, sizeof(int));fout.write((char*)&t1.c.data(), t1.c.length());//data()实际上调用的是c_str()方法fout.close();ifstream fin("test6.txt", ios::out|ios:binary);Test t2;fin.read((char*)&t2.a, sizeof(int));fin.read((char*)&len, sizeof(int)); //读第二个字符串的长度t2.b.resize(len);fin.read((char*)&t2.b[0], len);fin.read((char*)&len, sizeof(int));t2.b.resize(len);fin.read((char*)&t2.c[0], len);cout<<t2.a<<" "<<t2.b<<" "<<t2.c<<endl;fin.close();return 0;}

测试:

看乱码,首先是4个字节的整数,然后又是4个字节的整数,表示第一个字符串的长度,然后是第二个字符串的长度

write()成员函数

函数功能:以字节为单位向文件流中写入整块数据,最有价值的应用可以处理结构体变量和类对象函数原型:ostream& write( const char* pch, int nCount );函数参数:pch 写入的数据的指针nCount 写入数据的字节大小

read() 成员函数

函数功能:从文件流中读出整块数据函数原型:istream& read( char* pch, int nCount ); 函数参数:pch 用来接收数据的指针nCount 读取的字节数的大小

3.文件随机读写tellp、tellg、seekp、seekg

当前文件流活动指针

(1)文件流指针用以跟踪发生 I/O 操作的位置

(2)每当从流中读取或写入一个字符,当前活动指针就会向前移动

(3)当打开方式中不含有ios::ate或ios::app选项时,则文件指针被自动移到文件的开始位置,即字节地址为0的位置。

文件的随机读写 seekp和seekg:定位文件指针

函数功能seekp:设置输出文件流的文件流指针位置seekg:设置输入文件流的文件流指针位置函数原型:ostream& seekp( streampos pos );定位到某一个位置pos,基准点是文件的开头指定的ostream& seekp( streamoff off, ios::seek_dir dir );基准点可以是开头,结尾,或者文件当前位置,类似于Linux下的fseek,lseekistream& seekg( streampos pos );istream& seekg( streamoff off, ios::seek_dir dir );函数参数pos:新的文件流指针位置值off:需要偏移的值dir:搜索的起始位置

文件的随机读写tellp和tellg:获取当前文件流活动指针

输出流用tellp输入流用tellg函数功能tellp:获得输出的文件流指针的当前位置,以字节为单位tellg:获得输入的文件流指针的当前位置,以字节为单位函数原型:streampos tellp();streampos tellg();函数返回值:实际上是一个long类型

其他

C库fseek,ftellLinux系统调用lseeklseek(fd, 0, SEEK_CUR)seekp,seekg与C库中fseek相互对应(C库不区分输入流和输出流)tellp,tellg与C库中ftell相互对应seekp,seekg与Linux系统调用中lseek相互对应Linux系统调用没有对应的tell函数,而可以通过lseek(fd, 0, SEEK_CUR)实现类似功能,其返回值为当前文件指针的位置

seek_dir

dir参数用于对文件流指针的定位操作上,代表搜索的起始位置在ios中定义的枚举类型:enum seek_dir {beg, cur, end};每个枚举常量的含义:ios::beg:文件流的起始位置ios::cur:文件流的当前位置ios::end:文件流的结束位置

eg:P60\10.cpp

#include <cassert>#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;int main(void){ifstream fin("test7.txt");//文件输入流不会创建文件//如果文件不存在,打开会失败assert(fin);fin.seekg(2);//定位到字符cchar ch;fin.get(ch);cout<<ch<<endl;//输出最后一个字符//定位到文件结尾处,向前-1//文件流指针指向了末尾的地方fin.seekg(-1, ios::end);fin.get(ch);cout<<ch<<endl;//用以下方法可以获取文件的大小//获取文件流指针的位置//0是结束符的位置fin.seekg(0, ios::end);streampos pos = fin.tellg();cout<<pos<<endl;return 0;}

测试:

当前文件大小是7个字节

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。