资源预览内容
第1页 / 共28页
第2页 / 共28页
第3页 / 共28页
第4页 / 共28页
第5页 / 共28页
第6页 / 共28页
第7页 / 共28页
第8页 / 共28页
第9页 / 共28页
第10页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
面向对象程序设计第7章 文件处理西南交通大学信息科学与技术学院 “文件”,一般是指内存以外的存储介质上一批数据的集合。C+在语言层次上提供了文件操作的一系列函数用于完成文件的操作,打开、关闭文件,读取、写入文件数据等操作。 1。字符文件与二进制文件 字符文件字符文件:又称ASCII文件或文本TEXT文件,它是以一个字节存放一个ASCII码,代表一个字符。例如,32767需要使用5个字节表示,即: 51 50 55 54 55 (十进制表示的ASCII),而浮点数136.56需要使用6个字节表示,即49 51 54 46 53 54。 西南交通大学信息科学与技术学院 二进制文件二进制文件:是指以数据在内存中存储形式原样输出(存放)到文件上去,例136.56是一个float型实数,它在内存中占有4个字节长度。将该4个字节按其在内存中的原来形式存放到文件中。无论该float型数有多大,都只占用4个字节。 011111111111111101111111111111110011001100110010001101110011011000110111二进制形式表示ASCII形式表示32767整数32767在内存中的存储形式西南交通大学信息科学与技术学院 可见用ASCII码形式输出与字符一一对应,一个字节代表一个字符,因而便于对字符进行逐个处理,也便于输出字符,缺点是占存储空间较多。二进制文件节省存储空间,而且输入输出速度快,节省时间。 2。缓冲文件系统和非缓冲文件系统 缓冲文件系统缓冲文件系统是指:系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘文件中去。如果从磁盘向内存读入数据,则一次从磁盘文件中将一批数据输入到内存缓冲区,然后再从缓冲区逐个地将数据送到程序数据区。 非缓冲文件系统非缓冲文件系统是指:系统不自动开辟确定大小的缓冲区,而由程序员为每个文件设定缓冲区。 西南交通大学信息科学与技术学院输出输入输出文件缓冲区程序数据区输入文件缓冲区文件信息区内存外设文件类对象磁盘西南交通大学信息科学与技术学院3。文件操作 为了调用磁盘文件,缓冲文件系统为每一个文件开辟了一个“文件信息区”,用来存放与文件操作有关的信息。 在C+中,头文件fstream.h中定义了文件类(型),包括:ifstream: 它支持从输入文件中提取数据的各种操作;ofstream:它支持把数据写入文件中的各种操作;fstream: 支持数据的输入与输出操作。C+中文件操作的步骤(1). 定义一个文件类(型)的对象:方法如下:ifstream infile; ofstream outfile; fstream iofile;西南交通大学信息科学与技术学院(2). 打开文件:建立文件对象与磁盘文件之间的联系;(3). 对打开文件的操作:可以使用成员函数或“”“”运算符对文件进行读写操作。(4). 文件操作完成后,应该用成员函数关闭打开的文件。文件的打开和关闭(1)文件的打开 (open) 所谓“打开”,实际上是在程序和操作系统之间建立起联系,通过文件的打开操作为所处理的文件定义一个文件指针,文件指针并不是直接指向所处理的文件本身,而是指向内存中用于存放文件信息的文件信息区,在文件打开后文件信息区就与该文件建立了一对一的联系。然后使用文件类所提供的成员函数(类似于成员变量),将数据写入到对应的文件中去。西南交通大学信息科学与技术学院打开文件的方法可以有:a.定义的文件类的对象(变量)后,使用成员函数打开文件:ifstream infile;ofsream outfile;fstream file;infile.open(“myfile_in.txt”); /打开一个只读文件outfile.open(“myfile_out.txt”);/打开一个只写文件file.open(“myfile.txt”, ios:in);/以只读方式打开文件b.在定义文件类对象时直接打开文件: ifstream infile(“myfile_in.txt”);ofstream outfile(“myfile_out.txt”);fstream file(“myfile.txt”, ios:in);西南交通大学信息科学与技术学院(2)文件的打开方式在头文件ios.h中,定义了文件打开方式的枚举成员:enum open_modein = 0x01, /00000001按读方式打开文件out = 0x02,/00000010按写方式打开文件ate = 0x04,/00000100打开文件时将文件指针移到app = 0x08,/00001000 文件的结尾处trunc = 0x10,/00010000 打开文件时清除原有内容nocreate = ox20, /00100000noreplace = 0x40,/01000000binary = 0x80/10000000 以二进制方式打开文件;西南交通大学信息科学与技术学院每一种打开方式是以一个二进制位来表示的,所以可以用二进制位或运算“|”将允许的几种方式组合起来使用。如:ios:out | ios:ate /打开一个输出文件并将指针移到文件尾ios:in | ios:binary/打开一个二进制文件用于输入ios:out | ios:trunc/打开一个输出文件并清除原有内容西南交通大学信息科学与技术学院枚举常量名含义ios:in打开文件用于输入(读)操作。如果文件存在,将不被截掉,文件定位指针位于文件首,新的数据可写到文件中任何位置。ios:out打开文件用于输出(写)操作。如果文件存在,并且没有设置ios:app, ios:ate,ios:in值,则文件被截掉。ios:ate如果文件存在,将不被截掉。文件定位指针位于文件尾,新的数据可写到文件中任何位置。ios:app如果文件存在,将不被截掉。文件定位指针位于文件尾,新的数据附加到文件尾(不可重写已存在的文件数据)。ios:trunc如果文件已存在,则被截为0;如果指定ios:out,同时没有设置ios:app, ios:ate, ios:in,则该模式是隐含的。ios:nocreate如果文件不存在,则打开文件失败(不创建新文件)。ios:noreplace如果文件存在,打开时只能设置为ios:ate及ios:app方式。ios:binary指定文件以二进制方式打开,而不是缺省说明的文本方式。西南交通大学信息科学与技术学院由文件打开方式的说明可知:ifstream类的成员函数open的原型为:open(const char *, int = ios:in, int = filebuf:openprot);其缺省的文件打开方式为ios:in;ofstream类的成员函数open的原型为:open(const char *, int = ios:out, int = filebuf:openprot);其缺省的文件打开方式为ios:out;fstream类的成员函数open的原型为:open(const char *, int, int = filebuf:openprot);其缺省的文件打开方式必须指定。(3) 文件的关闭(close) “关闭”就是使文件指针变量不指向该文件,也就是使文件指针变量与文件“脱钩”,此后不能再通过该指针对其相连的文件进行读写操作,除非再次打开。西南交通大学信息科学与技术学院无论是ifstream、ofstream还是fstream,关闭文件的操作都是:close( ); 如:infile.close( ), outfile.close( ), file.close( );关闭文件时, 系统把与该文件相关联的内存缓冲区中的数据写到文件中,收回与该文件相关的文件信息区,把文件名与文件对象之间建立的关联断开。(4)文件操作的保护 在打开文件后,通常要判断打开是否成功。若打开成功,则文件类对象的值为非零值;若打开不成功,则其值为0。为此,打开文件的格式可以写为:ifstream f1(“file.dat”);if(!f1)cout“不能打开文件:”“file.dat”n;exit(1);西南交通大学信息科学与技术学院char filename256;coutfilename;ofstream f5;f5.open(filename);if(!f5)cout“不能打开文件:”“file.dat”和插入“”运算符。西南交通大学信息科学与技术学院例:编写程序,读取源程序文件并复制到目的文件中去。#include#includevoid main(void)char filename_in256, filename_out256;coutfilename_in;coutfilename_out;ifstream infile(filename_in);/ifstream infile;if(!infile)/infile.open(filename_in); cout“不能打开输入文件:filename_inn; exit(-1);ofstream outfile(filename_out);if(!outfile) cout不能打开输出文件:filename_outch) /当到达文件结尾时,结束循环; outfilech; /否则其返回值不为0,继续循环。infile.close( );outfile.close( );西南交通大学信息科学与技术学院处理文件复制问题的另外两个方案:方案2:(适用于任何类型的文件) char ch; /成员函数完成从源文件中字符读取, while(infile.get(ch) /这样将不会自动跳过空格。 outfile.put(ch); /将ch中的字符写到目的文件中。 infile.close( ); outfile.close( );方案3:(只适用于文本文件) char buff300; /从源文件中读取一行字符,不含n字符 while(infile.getline(buff,300) outfilebuffn; infile.close( ); outfile.close( );西南交通大学信息科学与技术学院(6)C+的二进制文件操作 C+的文件类对象可能通过成员函数read( )和write( )实现对二进制文件的读写操作是的,函数的原型为:read(char *buf, int size); 功能:从文件中读取由size所指定的字节数据到buf所指向的存储单元中。write(char *buf, int size);功能:将由buf所指向的存储单元中的size个字节数据写入到文件中。西南交通大学信息科学与技术学院例:产生一个二进制文件,将1500之间的所有偶数写入文件data.dat中。#include#includevoid main(void) ofstream outfile(d:sourcedata.dat,ios:out|ios:binary);if(!outfile)cout不能打开输出文件:data.datn;exit(-1);for(int i=2;i500;i+=2) outfile.write(char *)&i,sizeof(int); /将整数地址强制转换成字符指针outfile.close( );西南交通大学信息科学与技术学院例:从上例中产生的数据文件data.dat中读取二进制数据,并在显示器上按每行10个数据 的形式显示。#include#includevoid main(void)ifstream infile(d:sourcedata.dat,ios:binary);if(!infile)cout不能打开输入文件:data.datn; exit(-1); int a250;infile.read(char *)a,sizeof(int)*249);for(int i=0;i249;i+)coutait;if(i+1)%10=0) coutn;coutn;infile.close( );西南交通大学信息科学与技术学院处理文件复制问题的另一个方案:方案4:while(!infile.eof( )infile.read(buf, 4096);outfile.write(buf, 4096); /eof( ):用于测试文件结束,当文件结束时,函数返回非0;否则返回值为0; 该程序可以实现任意文件类型的拷贝,包括文本文件、数据文件甚至可执行文件。西南交通大学信息科学与技术学院(7)文件的随机访问 在文件信息区中存在一个用于指示当前文件读取位置的指针变量,称为文件定位指针,C+语言不仅允许按文件中信息的先后顺序来进行读写,同时也允许从文件中的任何位置开始进行数据的读写操作,这种读写方式就称为文件的随机访问。C+的istream和ostream类中分别提供了几个支持文件随机访问的成员函数。分别是:istream (输入文件)类:seekg(long streampos);将文件定位指针移动到strampos所指定的位置。seekg(long streamoff, seek_dir);将文件定位指针按seek_dir确定的方向移动streamoff位置;tellg( );返回输入文件中,文件定位指针当前的位置。西南交通大学信息科学与技术学院ostream (输出文件)类:seekp(long streampos);将文件定位指针移动到strampos所指定的位置。seekp(long streamoff, seek_dir);将文件定位指针按seek_dir确定的方向移动streamoff位置;tellp( ); 返回输出文件中,文件定位指针当前的位置。Seek_dir枚举常量值功能ios:beg0文件开头ios:cur1文件指针的当前位置ios:end2文件尾西南交通大学信息科学与技术学院例如:infile.seekg(500);/文件定位指针移到距文件头500个字节处infile.seekg(-100,ios:cur); /文件定位指针从当前位置前移100个字节infile.seekg(100,ios:cur);/文件定位指针从当前位置后移100个字节outfile.seekp(-100,ios:end);/文件定位指针从文件尾开始前移100个字节注:1.前移:指文件定位指针从文件尾向文件头方向移动(streamoff为负值); 后移:指文件定位指针从文件头向文件尾方向移动;2.在移动文件指针时,必须保证移动后的指针值大于0且小于等于文件尾字节编号,否则将导致接着的输入输出操作失败。西南交通大学信息科学与技术学院例:产生一个51000之间的奇数文件(二进制文件),将文件中的第2030之间的数读出后输出。#include#includevoid main(void) ofstream outfile(“data.dat”,ios:out|ios:binary); int i; for(i=5;i1000;i+=2) outfile.write(char *)&i, sizeof(int); outfile.close( ); ifstream infile(“data.dat”,ios:in|ios:binary); int x; infile.seekg(20*sizeof(int); for(i=0;i10;i+) infile.read(char *)&x,sizeof(int); coutxt; infile.close( );西南交通大学信息科学与技术学院例:设在A盘上已经存在一个二进制格式的文件,其中存放了由1开始的公差为2的一批数,下面的程序判断这批数的最后一个是否是99,如果不是的话,则在文件中已有的数的基础上以相同的规律将数补充到99为止。#include#include#includevoid main( ) int num, i; fstream fp;fp.open(a:data1.txt,ios:in|ios:out|ios:binary);if(!fp)coutfile cant open!; exit(-1); fp.seekg(-(long)sizeof(int),ios:end);fp.read(char *)&num,(long)sizeof(int);for(i=num+2;i”完成重构对象,而只用一个“”完成对象存入文件。 class inventory string Description; string No; int Quantity; double Cost; double Retail;public: inventory(string=#,string=0,int=0,double=0,double=0); friend ostream&operator(istream&sour,inventory&iv); ; /流类作为形式参数必须是引用西南交通大学信息科学与技术学院inventory:inventory(string des,string no,int quan, double cost,double ret) Description=des; No=no; Quantity=quan; Cost=cost; Retail=ret;ostream &operator(ostream&dist,inventory&iv) distleftsetw(20)iv.Descriptionsetw(10)iv.No; distrightsetw(10)iv.Quantitysetw(10)iv.Cost setw(10)iv.Retail(istream&sour,inventory&iv) souriv.Descriptioniv.Noiv.Quantity iv.Costiv.Retail; return sour; /从文件读出是自动把数字串转为数读出,函数体内功能不变西南交通大学信息科学与技术学院int main( ) inventory car1(夏利2000,805637928,156,80000,105000),car2; inventory motor1(金城125,93612575,302,10000,13000),motor2; ofstream distfile(d:Ex9_9.data); distfilecar1motor1; /注意ofstream是ostream的派生类 distfile.close(); coutcar1; coutmotor1; coutcar2; coutcar2motor2; sourfile.close(); coutcar2; coutmotor2; return 0;
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号