




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
作业报告学生姓名:学号:指导教师:学生E-mail:一、作业名称:带缓存的文件操作类二、作业要求在创立执行体程序库中的日志类的过程中,分析得出通过缓存向文件中写入数据时,能够提高读写磁盘的性能。本文根据这个思想,建立一个简单的文件操作的封装类,其内部对根本的文件操作函数〔open、lseek、read、write、close〕进行封装,对外提供读写操作接口,并提供数据的缓存效劳:1、调用该类的写操作接口时,数据要首先写到缓存中,再根据要求写入文件中;2、调用该类的度操作接口时,该类能够缓存读出的数据;3、读写缓存要保持一致性。三、设计与实现首先看下该封装类的定义:classEXFileOperator{public:EXFileOperator(constchar*_FileName);~EXFileOperator();voidF_READ(int_position,int_length);voidF_WRITE(constchar*pstrMsg);private:EXFileOperator();intReadFile(intposition,intlength);intWriteFile(constchar*pstrMsg);intFlush();constchar*FileName;int_fd;pthread_mutex_t*m_pMutex;char*m_pBuffer;unsignedintm_nUsedBytesForBuffer;};EXFileOperator类中F_READ和F_WRITE是该类对外提供的读写操作的接口,其中F_READ表示从给定位置(_Position)开始读出_length长度的文件内容;调用F_WRITE函数,将pstrMsg指向的信息串写入到文件中。内部ReadFile和WriteFile分别封装了文件read和write操作函数,lseek也封装在ReadFile中。在读操作之前和缓存缺乏时可调用Flush函数进行缓存的刷新。另外,类中还提供了保存一些信息的成员变量,包括需要操作的文件的文件名(FileName)、文件标识符(_fd),以及互斥量m_pMutex和缓存区(m_Buffer)。文件的翻开和关闭操作分别封装在该类的构造函数和析构函数中,设置缓存已用长度为0。假设互斥量初始化操作失败,那么需要进行一些去除工作。关闭文件后,还要撤销互斥量和回收缓存。EXFileOperator::EXFileOperator(constchar*_FileName){_fd=open(_FileName,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);if(_fd==-1)throw"InEXFileOperator::EXFileOperator(),openerror";m_pBuffer=newchar[BUFFER_SIZE];m_nUsedBytesForBuffer=0;m_pMutex=newpthread_mutex_t;if(pthread_mutex_init(m_pMutex,0)!=0){deletem_pMutex;delete[]m_pBuffer;close(_fd);throw"InEXFileOperator::EXFileOperator(),initerror";}}EXFileOperator::~EXFileOperator(){if(_fd!=0)close(_fd);if(m_pMutex!=0)deletem_pMutex;if(m_pBuffer!=0)delete[]m_pBuffer;}对文件读写操作的封装在ReadFile函数和WriteFile函数中。在进行读之前,需要对缓存进行刷新,保证能够读出最新的文件数据。如果需要读出的数据长度比拟大,大于缓存长读时,那么需要分批次读,每次先读到缓存中,再打印出;假设需要读出的数据长度较小,那么会一次性的读到缓存再打印出。intEXFileOperator::ReadFile(intposition,intlength){Flush();if(pthread_mutex_lock(m_pMutex)!=0)throw"pthread_mutex_lockfailed......";……intr;if(length==0){ cout<<""<<endl; cout<<"youwanttoreadnothing"<<endl;}while(length>0){r=read(_fd,m_pBuffer,length);if(r==-1){cout<<"readfailed......"<<endl;break;}if(r==0){cout<<""<<endl;cout<<"theendofthefile......"<<endl;break;}cout<<m_pBuffer;lseek(_fd,r,SEEK_CUR);//重新修改偏移量〔定位〕length-=r;//剩余待读数据长度。}if(pthread_mutex_unlock(m_pMutex)!=0)throw"pthread_mutex_unlockfailed......";return0;}对于WriteFile函数,要根据写入数据长度与缓存大小的相对性进行不同方式的写操作。假设需写入的数据长度大于缓存大小,显然无法写到缓存中,这时就直接写入到文件中;假设写入数据的长度小于缓存大小,那么需要先写入缓存,而且当剩余缓存缺乏时,要先对缓存进行刷新。intEXFileOperator::WriteFile(constchar*pstrMsg){……………if(pthread_mutex_lock(m_pMutex)!=0)return-1;unsignedintlen_strmsg=strlen(pstrMsg);unsignedintm_nleftroom=BUFFER_SIZE-m_nUsedBytesForBuffer;if(len_strmsg>BUFFER_SIZE){if(_fd==-1)return-1;intw=write(_fd,pstrMsg,len_strmsg);if(w==-1)return-1;returnw;}if(len_strmsg>m_nleftroom){if(Flush()==-1)return-1;}memcpy(m_pBuffer+m_nUsedBytesForBuffer,pstrMsg,len_strmsg);m_nUsedBytesForBuffer+=len_strmsg;if(pthread_mutex_unlock(m_pMutex)!=0)return-1;return0;}为保证读写缓存的一致性,在读写操作中,都先对缓存进行互斥量加锁,操作结束后进行解锁。最后我们来看看缓存的刷新操作是如何实现的。同样需要对缓存进行互斥量的加锁,保证其一致性。刷新的主要工作就是将缓存中的数据写入到文件中。操作结束后进行互斥量解锁操作,刷新成功返回写入的数据长度,否那么返回-1。intEXFileOperator::Flush(){………………if(pthread_mutex_lock(m_pMutex)!=0)return-1;………………intw=write(_fd,m_pBuffer,m_nUsedBytesForBuffer);………………m_nUsedBytesForBuffer=0;if(pthread_mutex_unlock(m_pMutex)!=0)return-1;returnw;}四、测试到这里文件操作的封装类已经根本设计完成,下面进行一些简单的测试。首先测试对文件进行写操作的功能实现,根据策略,先写入少量信息,即数据长度小于缓存长度〔设置为64〕时,查看数据是在文件中还是在缓存中。测试代码〔1〕如下:intmain(){EXFileOperator*Opt=newEXFileOperator("test2.txt");Opt->F_WRITE("WuXuanle202321060208");}测试代码(1)想要向文件中写入"WuXuanle202321060208"(长度<64),验证结果如图4-1所示,我们可以看到,成功完成对文件的写操作,但文件中并没有测试中想要写入的内容,这是因为该局部内容还在缓存中。为验证测试代码〔1〕中,写入内容在缓存中,而没有写入文件中,我们增加一次写操作,且这次写入数据长度仍然小于缓存大小,但加上第一次写的内容,图4-1测试代码〔1〕的验证结果数据长度要大于缓存大小。测试代码〔2〕如下:intmain(){EXFileOperator*Opt=newEXFileOperator("test2.txt");Opt->F_WRITE("WuXuanle202321060208");Opt->F_WRITE("UniversityofElectronicScienceandTechologyofChina");}测试代码〔2〕进行了两次写操作,验证结果如图4-2所示。从中可以看出两次写操作都已成功,而且文件中出现了第一次写的内容,而第二次写的内容没有出现。分析一下,由于第一次写入数据暂存在缓存中,而使得第二次写时,剩余缓存缺乏,会先进行刷新操作,这样第一次写的内容就会被写入到文件中,而第二次写的内容仍在缓存中。图4-2测试代码〔2〕的验证结果最后进行读操作的测试,代码〔3〕如下:intmain(){EXFileOperator*Opt=newEXFileOperator("test2.txt");Opt->F_WRITE("WuXuanle202321060208");Opt->F_WRITE("UniversityofElectronicScienceandTechologyofChina");Opt->F_READ(28,23);Opt->F_READ(51,56);Opt->F_READ(0,110);}其验证结果如图4-3所示。图4-3测试代码〔3〕的验证结果五、对本课程或本作业的建议和意见本次作业涉及到文件操作的封装,并要求通过缓存来提高读写磁盘的性能,这样一些细节问题就要考虑到封装类的设计中,并在最后进行屡次测试,验证封装类的功能和效果。六、附录代码局部:#include<fcntl.h>#include<unistd.h>#include<iostream>#include<errno.h>#include<pthread.h>#include<stdio.h>#include<stdlib.h>#include"EXFileOperator.h"usingnamespacestd;#defineBUFFER_SIZE64//缓存大小,设置为64EXFileOperator::EXFileOperator(constchar*_FileName){//翻开文件,并进行初始化工作_fd=open(_FileName,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);if(_fd==-1) throw"InEXFileOperator::EXFileOperator(),openerror";m_pBuffer=newchar[BUFFER_SIZE];//创立缓存区m_nUsedBytesForBuffer=0;//设置已用缓存区大小为0m_pMutex=newpthread_mutex_t;//创立互斥量对象if(pthread_mutex_init(m_pMutex,0)!=0){//缓存正在被访问,此次加锁失败deletem_pMutex;delete[]m_pBuffer;close(_fd);throw"InEXFileOperator::EXFileOperator(),initerror";}}EXFileOperator::~EXFileOperator(){//关闭文件,并进行互斥量的撤销和缓存的回收if(_fd!=0)close(_fd);if(m_pMutex!=0)deletem_pMutex;if(m_pBuffer!=0)delete[]m_pBuffer;}voidEXFileOperator::F_WRITE(constchar*pstrMsg){//对外提供写操作接口if(WriteFile(pstrMsg)==-1)//调用WriteFile函数cout<<"writefailed............"<<endl;elsecout<<"writesuccessfully..........."<<endl;}intEXFileOperator::WriteFile(constchar*pstrMsg){if(pstrMsg==0)return-1;if(strlen(pstrMsg)==0)return-1;if(m_pBuffer==0)return-1;if(pthread_mutex_lock(m_pMutex)!=0)return-1;unsignedintlen_strmsg=strlen(pstrMsg);//获取写入信息的大小unsignedintm_nleftroom=BUFFER_SIZE-m_nUsedBytesForBuffer;//剩余缓存大小if(len_strmsg>BUFFER_SIZE){//待写入信息长度大于缓存区大小时,直接写入文件if(_fd==-1)return-1;intw=write(_fd,pstrMsg,len_strmsg);if(w==-1)return-1;returnw;}if(len_strmsg>m_nleftroom){//剩余缓存区缺乏时,刷新缓存if(Flush()==-1)return-1;}memcpy(m_pBuffer+m_nUsedBytesForBuffer,pstrMsg,len_strmsg);//写入缓存m_nUsedBytesForBuffer+=len_strmsg;//修改已用缓存大小if(pthread_mutex_unlock(m_pMutex)!=0)return-1;return0;}voidEXFileOperator::F_READ(int_position,int_length){//对外提供读操作接口if(ReadFile(_position,_length)==-1)cout<<"readingfailed......"<<endl;else{cout<<""<<endl;//换行cout<<"theresultsreadabove......"<<endl;}}intEXFileOperator::ReadFile(intposition,intlength){Flush();//读之前进行刷新if(pthread_mutex_lock(m_pMutex)!=0)throw"pthread_mutex_lockfailed......";if(_fd==-1)return-1;if(lseek(_fd,position,SEEK_SET)==-1)return-1;intr;if(length==0){//不读出数据 cout<<""<<endl; cout<<"youwanttoreadnothing"<<endl;}while(length>0){//分段读出长度为length的数据r=read(_fd,m_pBuffer,length);//读入缓存if(r==-1){cout<<"readfailed......"<<endl;break;}if(r==0){cout<<""<<endl;cout<<"theendofthefile......"<<endl;break;}cout<<m_pBuffer;//打印出要读出的数据lseek(_fd,r,SEEK_CUR);//修改偏移量,准备下一次读length-=r;//剩余读数据长度
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 福建省宁德2025届高考冲刺押题(最后一卷)化学试卷含解析
- 基因突变影响的实例研究试题及答案
- 2024年CPMM数据分析试题及答案
- 《安全工程师》2024年安国市高分冲刺试卷含解析
- 跨国物流协作机制试题及答案
- CPSM职业生涯规划与考试相关性试题及答案
- 供应链动态管理的关键问题试题及答案
- 提升CPMM自身能力的试题及答案
- 2025届天津市静海区大邱庄中学高三第三次模拟考试化学试卷含解析
- 乘风破浪 2024年国际物流师备考试题及答案
- 2024年陕西安康市宁陕县事业单位遴选29人历年【重点基础提升】模拟试题(共500题)附带答案详解
- 房地产项目后评估报告
- JBT 14716-2023 增材制造装备 面曝光光固化三维打印机 (正式版)
- 基于STM32的室内空气质量监测系统的研究与实现
- 上海市黄浦区2024届高三二模语文试题(解析版)
- 高考志愿填报指导高考志愿填报指南
- 2024年山东省潍坊市昌邑市中考一模数学试题
- GB/T 6346.1-2024电子设备用固定电容器第1部分:总规范
- 2024年杭州市水务集团有限公司招聘笔试参考题库附带答案详解
- (2024年)中华人民共和国环境保护法全
- (高清版)DZT 0280-2015 可控源音频大地电磁法技术规程
评论
0/150
提交评论