&&&&&&&上一节中鸡啄米讲了定时器timer的用法,本节介绍下文件操作类cfile类的使用。

&&&&&& cfile类概述

&&&&&&&如果你学过c语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作。这些文件操作函数中有的最终还是调用了操作系统的api函数或者处理过程与之类似,例如在windows系统中,fread函数就调用了api函数readfile。

&&&&&&&windows系统的api函数除了readfile,还有createfile、writefile等函数。而mfc基于面向对象的思想,将这些windows api函数封装到了cfile类中,实现对文件的打开、关闭、读、写、获取文件信息等操作。使用cfile类对文件进行操作非常便捷。

&&&&&& cfile类的成员函数

&&&&&& cfile( );
&&&&&& cfile(handle hfile);
&&&&&& cfile(lpctstr lpszfilename,uint nopenflags);

&&&&&& 以上三个成员函数都是cfile的构造函数,用于构造cfile对象。参数hfile为要关联到cfile对象的文件的句柄。参数lpszfilename为要关联到cfile对象的文件的相对路径或者绝对路径;参数nopenflags为文件访问选项的组合,通过各选项的按位或运算实现组合,下面的5个表列出了nopenflags参数可能取的选项:

&&&&&& 下面的文件访问模式选项表中只能选择一个进行组合,默认取cfile::moderead。

取值 描述
cfile::moderead 只读方式访问文件
cfile::modewrite 写入方式访问文件
cfile::modereadwrite 读写方式访问文件

&&&&&& 下面的文件共享模式选项表中也只能选择一个进行组合,默认的共享模式是cfile::shareexclusive。

取值 描述
cfile::sharedenynone 允许其他进程对文件进行读写
cfile::sharedenyread 不允许其他进程读取文件
cfile::sharedenywrite 不允许其他进程写文件
cfile::shareexclusive 禁止其他进程对文件的所有访问

&&&&&&&下面的文件创建模式选项列表中可选择第一个或两者都选进行组合。

取值 描述
cfile::modecreate 如果文件不存在则创建文件,而如果存在则将它关联到此cfile对象并将长度截取为0
cfile::modenotruncate 如果文件不存在则创建文件,而如果存在则将它关联到此cfile对象而不进行截取

&&&&&& 注意,选择cfile::modenotruncate时需要与cfile::modecreate一起使用,即cfile::modecreate | cfile::modenotruncate。

&&&&&& 另外,还有一个文件缓冲选项列表和一个文件安全选项。文件缓冲选项不太常用,鸡啄米这里就不讲了,有兴趣的可以查阅msdn。文件安全选项是cfile::modenoinherit,意为禁止子进程继承使用此文件。

&&&&&& 当然,在实际使用时,以上各个表并不是都要用到,大家可以根据自己的需要选择用哪个表,选择哪个选项。

&&&&&& virtual bool open(lpctstr lpszfilename,uint nopenflags,cfileexception* perror = null);

&&&&&& 打开文件。它通常与默认构造函数cfile::cfile()一起使用。参数lpszfilename和nopenflags同构造函数。参数perror为指向文件异常对象的指针,默认为null。

&&&&&& virtual void close( );

&&&&&& 关闭文件。如果你没有在执行析构函数前调用此成员函数关闭文件,则析构函数会为你关闭。

&&&&&& virtual uint read(void* lpbuf,uint ncount);

&&&&&&&读取文件数据到缓存。参数lpbuf是由用户提供的指向接收文件数据的缓存的指针;参数ncount为读取的最大字节数。返回值是实际读取到缓存的字节数,如果到达文件尾则返回值可能会小于ncount,此时继续读取的话,会返回0,所以通常我们都会判断返回值是否小于ncount或者等于0来确定是否到达文件尾。

&&&&&& virtual void write(const void* lpbuf,uint ncount);

&&&&&& 将缓存中的数据写入文件。参数lpbuf也是由用户提供,指向包含写入数据的缓存的指针;参数ncount为缓存中要被写入文件的数据的字节数。

&&&&&& virtual ulonglong seek(longlong loff,uint nfrom);

&&&&&& 在一个打开的文件中重定位文件指针。参数loff为文件指针移动的字节个数,为正数时表示向文件尾移动,为负数时表示向文件开头移动;参数nfrom为loff的基准位置,即由nfrom位置开始移动loff个字节,它可以取下面几个值中的一个:

&&&&&& cfile::begin&&&&&& 从文件开头开始移动
&&&&&& cfile::current&&& 从文件指针的当前位置开始移动&
&&&&&&&cfile::end&&&&&&&&& 从文件尾开始移动

&&&&&& 文件打开时,文件指针被置于0,即文件开头处。

&&&&&& 如果此函数成功则返回文件指针的位置。

&&&&&& void seektobegin( );

&&&&&& 将文件指针移动到文件开头。它等价于seek( 0l, cfile::begin )。

&&&&&& ulonglong seektoend( );

&&&&&& 将文件指针移动到文件末尾。返回值是文件的字节长度。它等价于cfile::seek( 0l, cfile::end )。

&&&&&& virtual ulonglong getlength( ) const;

&&&&&& 获取文件的字节长度。

&&&&&& virtual void setlength(ulonglong dwnewlen);

&&&&&& 改变文件的长度。参数dwnewlen为文件的新长度,它可能比文件的当前长度值要大或者小,文件会相应的被扩展或截取。

&&&&&& virtual cstring getfilename( ) const;

&&&&&& 获取文件名称。

&&&&&& virtual cstring getfilepath( ) const;

&&&&&& 获取文件的绝对路径。

&&&&&& virtual cstring getfiletitle( ) const;

&&&&&& 获取文件的显示名称。举个例子,与getfilename区分一下,如果你系统中的文件不显示扩展名,则它获取到的文件名称就不包含扩展名,否则就显示扩展名。

&&&&&& virtual ulonglong getposition( ) const;

&&&&&&&获取文件指针的当前位置。

&&&&&& static void pascal remove(lpctstr lpszfilename,catltransactionmanager* ptm = null);

&&&&&& 删除文件。参数lpszfilename为要删除的文件路径,可以是相对路径、绝对路径或者网络路径;参数ptm指向一个catltransactionmanager对象。

&&&&&& static void pascal rename(lpctstr lpszoldname,lpctstr lpsznewname,catltransactionmanager* ptm = null);

&&&&&& 重命名文件。参数lpszoldname为老的文件路径;参数lpsznewname为新的文件路径;参数ptm指向一个catltransactionmanager对象。实际上此函数的意义已经不只是重命名文件,还可以移动文件到其他目录下,例如,lpszoldname取"d:\\1.txt",lpsznewname取"e:\\2.txt",这样可以将d盘中的1.txt文件转移到e盘并重命名为2.txt。

&&&&&& cfile类应用实例

&&&&&& 这里鸡啄米只给大家演示几个简单的代码片段,从这些代码片段中熟悉cfile类的文件操作。

&&&&&& 实例一:构造cfile对象时就打开文件,然后向文件中写入数据,最后以seek函数移动文件指针,读取文件内容。

c++代码
  1. char&writebuffer[500];&&&&&//&要写入的数据的缓存 &&
  2. char&readbuffer[500];&&&&&&//&存放读取数据的缓存 &&
  3. longlong&loff&=&0;&&&&&&&&&//&文件指针的偏移量,也是读取到的数据的总字节数&&
  4. //&构造cfile对象,同时以创建和读写的方式打开文件e:\1.txt &&
  5. cfile&file(_t("e:\\1.txt"),&cfile::modecreate&|&cfile::modereadwrite); &&
  6. &&
  7. //&将写入数据的缓存中每个字节都赋值为字符c &&
  8. memset(writebuffer,&'c',&sizeof(writebuffer)); &&
  9. //&将数据写入到文件中 &&
  10. file.write(writebuffer,&sizeof(writebuffer)); &&
  11. &&
  12. while&(true) &&
  13. { &&
  14. &&&&//&以文件开头为基准,移动文件指针到loff的位置 &&
  15. &&&&file.seek(loff,&cfile::begin); &&
  16. &&&&//&读取100个字节的数据到存放读取数据的缓存的readbuffer&+&loff位置处 &&
  17. &&&&int&nret&=&file.read(readbuffer&+&loff,&100); &&
  18. &&&&//&根据实际读取的字节数,增加文件指针的移动量 &&
  19. &&&&loff&+=&nret; &&
  20. &&&&//&如果读取数据时返回值小于指定的100,说明已到文件尾,跳出循环 &&
  21. &&&&if&(nret&<&100) &&
  22. &&&&&&&&break; &&
  23. } &&
  24. &&
  25. //&关闭文件 &&
  26. file.close();&&

&&&&&& 实际上,在write函数和read函数执行后,文件指针会自动移动到最后操作的位置,所以其实上面的代码中无须使用seek函数再去手动移动文件指针。这将在下面的实例二中体现出来。

&&&&&& 实例二:构造cfile对象,然后使用open成员函数打开文件,再写入一个结构体数组,最后读取出来。

&&&&&& 先贴上结构体的定义:

c++代码
  1. struct&student &&
  2. { &&
  3. &&&&int&&nnum; &&&&
  4. &&&&float&fscore; &&
  5. };&&

&&&&&&&下面是文件操作的代码片段:

c++代码
  1. student&s1[2];&&&//&存放要写入文件的数据 &&
  2. student&s2[2];&&&//&存放从文件读取的数据 &&
  3. cfile&file;&&&&&&//&cfile对象 &&
  4. int&nreadbytes&=&0;&&&//&从文件中读取到的总字节数 &&
  5. &&
  6. //&为s1数组各元素赋值 &&
  7. s1[0].nnum&=&22; &&
  8. s1[0].fscore&=&91.5; &&
  9. s1[1].nnum&=&23; &&
  10. s1[1].fscore&=&85; &&
  11. &&
  12. //&以创建、读写方式打开文件e:\1.txt &&
  13. if&(file.open(_t("e:\\1.txt"),&cfile::modecreate&|&cfile::modereadwrite)) &&
  14. { &&
  15. &&&&//&写入数据s1结构体数组 &&
  16. &&&&file.write(s1,&sizeof(s1)); &&
  17. &&&&//&因为上面调用write以后文件指针在文件尾,所以需要将其移动到文件开头 &&
  18. &&&&file.seektobegin(); &&
  19. &&
  20. &&&&while&(true) &&
  21. &&&&{ &&
  22. &&&&&&&&//&读取数据到s2 &&
  23. &&&&&&&&int&nret&=&file.read((byte*)s2&+&nreadbytes,&sizeof(student)); &&
  24. &&&&&&&&//&计算已经读取到的总字节数 &&
  25. &&&&&&&&nreadbytes&+=&nret; &&
  26. &&&&&&&&//&如果读取数据时返回值小于指定的sizeof(student),则说明已到文件尾,跳出循环 &&
  27. &&&&&&&&if&(nret&<&sizeof(student)) &&
  28. &&&&&&&&&&&&break; &&
  29. &&&&} &&
  30. &&
  31. &&&&//&关闭文件 &&
  32. &&&&file.close(); &&
  33. }&&

&&&&&& 本节内容就到这里,如果有其他语言的文件操作的经验的话,应该还是比较简单的。鸡啄米很高兴能在大家的编程入门之路上贡献自己一点微薄的力量。

除非特别注明,鸡啄米文章均为原创
转载请标明本文地址:http://www.jizhuomi.com/software/234.html
2012-9-9 19:44:51
作者:鸡啄米 分类:软件开发 浏览: 评论:5