《2022年Linux高级环境编程实验报告 .pdf》由会员分享,可在线阅读,更多相关《2022年Linux高级环境编程实验报告 .pdf(9页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、作业报告学生姓名:学 号:指导教师:学生 E-mail:一、作业名称:带缓存的文件操作类二、作业要求在创建执行体程序库中的日志类的过程中,分析得出通过缓存向文件中写入数据时,能够提高读写磁盘的性能。本文根据这个思想,建立一个简单的文件操作的封装类,其内部对基本的文件操作函数(open、lseek、read、write、close)进行封装,对外提供读写操作接口,并提供数据的缓存服务:1、调用该类的写操作接口时,数据要首先写到缓存中,再根据要求写入文件中;2、调用该类的度操作接口时,该类能够缓存读出的数据;3、读写缓存要保持一致性。三、设计与实现首先看下该封装类的定义:class EXFileO
2、perator public:EXFileOperator(const char*_FileName);EXFileOperator();void F_READ(int _position,int _length);void F_WRITE(const char*pstrMsg);private:EXFileOperator();int ReadFile(int position,int length);int WriteFile(const char*pstrMsg);int Flush();const char*FileName;int _fd;pthread_mutex_t*m_pMut
3、ex;char*m_pBuffer;unsigned int m_nUsedBytesForBuffer;名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 9 页 -EXFileOperator 类中 F_READ 和 F_WRITE 是该类对外提供的读写操作的接口,其中 F_READ 表示从给定位置(_Position)开始读出 _length 长度的文件内容;调用 F_WRITE 函数,将 pstrMsg指向的信息串写入到文件中。内部 ReadFile和 WriteFile 分别封装了文件 read和 write 操作函数,lseek也封装在 ReadFile中。在读操作之前和
4、缓存不足时可调用Flush 函数进行缓存的刷新。另外,类中还提供了保存一些信息的成员变量,包括需要操作的文件的文件名(FileName)、文件标识符(_fd),以及互斥量 m_pMutex 和缓存区(m_Buffer)。文件的打开和关闭操作分别封装在该类的构造函数和析构函数中,设置缓存已用长度为 0。若互斥量初始化操作失败,则需要进行一些清除工作。关闭文件后,还要撤销互斥量和回收缓存。EXFileOperator:EXFileOperator(const char*_FileName)_fd=open(_FileName,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IW
5、USR);if(_fd=-1)throw In EXFileOperator:EXFileOperator(),open error;m_pBuffer=new charBUFFER_SIZE;m_nUsedBytesForBuffer=0;m_pMutex=new pthread_mutex_t;if(pthread_mutex_init(m_pMutex,0)!=0)delete m_pMutex;delete m_pBuffer;close(_fd);throw In EXFileOperator:EXFileOperator(),init error;EXFileOperator:EX
6、FileOperator()if(_fd!=0)close(_fd);if(m_pMutex!=0)delete m_pMutex;if(m_pBuffer!=0)delete m_pBuffer;对文件读写操作的封装在ReadFile函数和 WriteFile 函数中。在进行读之前,需要对缓存进行刷新,保证能够读出最新的文件数据。如果需要读出的数据长度比较大,大于缓存长读时,则需要分批次读,每次先读到缓存中,再打印出;若需要读出的数据长度较小,则会一次性的读到缓存再打印出。int EXFileOperator:ReadFile(int position,int length)Flush();
7、if(pthread_mutex_lock(m_pMutex)!=0)throw pthread_mutex_lock failed.;int r;名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 9 页 -if(length=0)coutendl;coutyou want to read nothing0)r=read(_fd,m_pBuffer,length);if(r=-1)coutread failed.endl;break;if(r=0)coutendl;coutthe end of the file.endl;break;coutBUFFER_SIZE)if(_fd=-
8、1)return-1;int w=write(_fd,pstrMsg,len_strmsg);if(w=-1)return-1;return w;if(len_strmsgm_nleftroom)if(Flush()=-1)return-1;memcpy(m_pBuffer+m_nUsedBytesForBuffer,pstrMsg,len_strmsg);m_nUsedBytesForBuffer+=len_strmsg;名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 9 页 -if(pthread_mutex_unlock(m_pMutex)!=0)return-1;retu
9、rn 0;为保证读写缓存的一致性,在读写操作中,都先对缓存进行互斥量加锁,操作结束后进行解锁。最后我们来看看缓存的刷新操作是如何实现的。同样需要对缓存进行互斥量的加锁,保证其一致性。刷新的主要工作就是将缓存中的数据写入到文件中。操作结束后进行互斥量解锁操作,刷新成功返回写入的数据长度,否则返回-1。int EXFileOperator:Flush()if(pthread_mutex_lock(m_pMutex)!=0)return-1;int w=write(_fd,m_pBuffer,m_nUsedBytesForBuffer);m_nUsedBytesForBuffer=0;if(pthr
10、ead_mutex_unlock(m_pMutex)!=0)return-1;return w;四、测试到这里文件操作的封装类已经基本设计完成,下面进行一些简单的测试。首先测试对文件进行写操作的功能实现,根据策略,先写入少量信息,即数据长度小于缓存长度(设置为64)时,查看数据是在文件中还是在缓存中。测试代码(1)如下:int main()EXFileOperator*Opt=new EXFileOperator(test2.txt);Opt-F_WRITE(Wu Xuanle 201321060208);测试代码(1)想要向文件中写入 Wu Xuanle 201321060208(长度F_W
11、RITE(Wu Xuanle 201321060208);Opt-F_WRITE(University of Electronic Science and Techology of China);测试代码(2)进行了两次写操作,验证结果如图4-2 所示。从中可以看出两次写操作都已成功,而且文件中出现了第一次写的内容,而第二次写的内容没有出现。分析一下,由于第一次写入数据暂存在缓存中,而使得第二次写时,剩余缓存不足,会先进行刷新操作,这样第一次写的内容就会被写入到文件中,而第二次写的内容仍在缓存中。图 4-2 测试代码(2)的验证结果最后进行读操作的测试,代码(3)如下:名师资料总结-精品资料欢
12、迎下载-名师精心整理-第 5 页,共 9 页 -int main()EXFileOperator*Opt=new EXFileOperator(test2.txt);Opt-F_WRITE(Wu Xuanle 201321060208);Opt-F_WRITE(University of Electronic Science and Techology of China);Opt-F_READ(28,23);Opt-F_READ(51,56);Opt-F_READ(0,110);其验证结果如图4-3 所示。图 4-3 测试代码(3)的验证结果五、对本课程或本作业的建议和意见本次作业涉及到文件操
13、作的封装,并要求通过缓存来提高读写磁盘的性能,这样一些细节问题就要考虑到封装类的设计中,并在最后进行多次测试,验证封装类的功能和效果。六、附录代码部分:#include#include#include#include#include 名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 9 页 -#include#include#includeEXFileOperator.h using namespace std;#define BUFFER_SIZE 64/缓存大小,设置为64 EXFileOperator:EXFileOperator(const char*_FileName)/
14、打开文件,并进行初始化工作_fd=open(_FileName,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);if(_fd=-1)throw In EXFileOperator:EXFileOperator(),open error;m_pBuffer=new charBUFFER_SIZE;/创建缓存区m_nUsedBytesForBuffer=0;/设置已用缓存区大小为0 m_pMutex=new pthread_mutex_t;/创建互斥量对象if(pthread_mutex_init(m_pMutex,0)!=0)/缓存正在被访问,此次加锁失败del
15、ete m_pMutex;delete m_pBuffer;close(_fd);throw In EXFileOperator:EXFileOperator(),init error;EXFileOperator:EXFileOperator()/关闭文件,并进行互斥量的撤销和缓存的回收if(_fd!=0)close(_fd);if(m_pMutex!=0)delete m_pMutex;if(m_pBuffer!=0)delete m_pBuffer;void EXFileOperator:F_WRITE(const char*pstrMsg)/对外提供写操作接口if(WriteFile(
16、pstrMsg)=-1)/调用 WriteFile 函数coutwrite failed.endl;else coutwrite successfully.BUFFER_SIZE)/待写入信息长度大于缓存区大小时,直接写入文件if(_fd=-1)return-1;int w=write(_fd,pstrMsg,len_strmsg);if(w=-1)return-1;return w;if(len_strmsgm_nleftroom)/剩余缓存区不足时,刷新缓存名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 9 页 -if(Flush()=-1)return-1;memcpy(m
17、_pBuffer+m_nUsedBytesForBuffer,pstrMsg,len_strmsg);/写入缓存m_nUsedBytesForBuffer+=len_strmsg;/修改已用缓存大小if(pthread_mutex_unlock(m_pMutex)!=0)return-1;return 0;void EXFileOperator:F_READ(int _position,int _length)/对外提供读操作接口if(ReadFile(_position,_length)=-1)coutreading failed.endl;else coutendl;/换行coutthe
18、results read above.endl;int EXFileOperator:ReadFile(int position,int length)Flush();/读之前进行刷新if(pthread_mutex_lock(m_pMutex)!=0)throw pthread_mutex_lock failed.;if(_fd=-1)return-1;if(lseek(_fd,position,SEEK_SET)=-1)return-1;int r;if(length=0)/不读出数据coutendl;coutyou want to read nothing0)/分段读出长度为length
19、 的数据r=read(_fd,m_pBuffer,length);/读入缓存if(r=-1)coutread failed.endl;break;if(r=0)coutendl;coutthe end of the file.endl;break;coutm_pBuffer;/打印出要读出的数据lseek(_fd,r,SEEK_CUR);/修改偏移量,准备下一次读length-=r;/剩余读数据长度 if(pthread_mutex_unlock(m_pMutex)!=0)throw pthread_mutex_unlock failed.;return 0;名师资料总结-精品资料欢迎下载-名
20、师精心整理-第 8 页,共 9 页 -int EXFileOperator:Flush()/刷新函数if(m_pBuffer=0)return-1;if(m_nUsedBytesForBuffer=0)return-1;/缓存中无数据if(pthread_mutex_lock(m_pMutex)!=0)return-1;if(_fd=-1)return-1;int w=write(_fd,m_pBuffer,m_nUsedBytesForBuffer);/写入文件if(w=-1)return-1;m_nUsedBytesForBuffer=0;/重新设置已用缓存区为0 if(pthread_m
21、utex_unlock(m_pMutex)!=0)return-1;return w;/返回写入数据的长度 测试代码部分:(三次测试代码集中在一起)#include#includeEXFileOperator.h using namespace std;int main()EXFileOperator*Opt=new EXFileOperator(test2.txt);Opt-F_WRITE(Wu Xuanle 201321060208);/第一次写Opt-F_WRITE(University of Electronic Science and Techology of China);/第二次写Opt-F_READ(28,23);Opt-F_READ(51,56);Opt-F_READ(0,110);名师资料总结-精品资料欢迎下载-名师精心整理-第 9 页,共 9 页 -