文件处理函数如何使用?用法举例,C与MFC

C语言,有时候真不得不佩它,照理说,文件处理函数是没有什么好讲的,但对于很多C入门的人来说,似乎也是值得静心品味一番的。

C中的文件处理函数并不很多,而常用的,似乎更少。

函数不难,但并不代表文件处理也不难。似乎又要有点跑题了,我总是喜欢跑题。上几天做梦,梦到我掉到月球上去啦……

对文件的操作,无非就是打开、读写、调整读写偏移指针以及关闭,似乎么什可说的,也许事实也的确如此。还是让我们来看一段经典代码吧,这代码可是我自己写的。

FILE* fp = fopen(”test.txt”, “r”); assert(fp); //打开文件,给一个断言,这是一种好习惯

fseek(fp, 0, SEEK_END); //把偏移指针指向文件的结尾

unsigned int nlen = ftell(fp); //返回当前的偏移指针,也就是返回刚刚设定的文尾位置

fseek(fp, 0, SEEK_SET); //把读写偏移指针指向文件的开头

char* const _psz = (char*)malloc(nlen + 1); //申请一段堆内存,这里的_psz为什么要被const修饰呢?

unsigned int size = fread(_psz, sizeof(char), nlen, fp); //读出文件的内容

_psz[size] = ‘/0′; //注意,必须要在字符串的结尾处添加结束标志,否则,哼哼!

fclose(fp); //关闭文件

…… //东搞搞,西搞搞

free(_psz); //归还堆内存

实在是太简单了是吧?是的,我正这样认为呢。

在读文件的时候,有点东西还是要说说的。因为我们都听说过,文件有两种格式,一种是文本,一种是二进制。文本文件,当然,我们不想说什么了,但二进制文件的读写,却值得一提。二进制的文件这样打开:

FILE* fp = fopen(”test.exe”, “rb”); assert(fp);

当然,可执行文件只不过是二进制文件的一个代表,在使用读写标志的时候,我们需要”b”后缀,表明打开的是二进制的文件。其实,这不是关键,而正真关键的部分是对文件的读写,这份代码有点冗余,但不写又怕给人闹出强迫症。

fseek(fp, 0, SEEK_END); //获取文件大小

size_t nlen = ftell(fp);

fseek(fp, 0, SEEK_SET);

unsigned char* const _psz = (unsigned char*)malloc(nlen + 1); //显然,申请的内存应该是BYTE格式

fread(_psz, sizeof(unsigned char), nlen, fp); //由于是二进制的文件,我们不必再对内存做处理

fclose(fp);

通常,这种用法不常见,而更多的对二进制文件的读写,是出现在socket上。比如,我们要从网上更新一个可执行文件,那么必须使用二进制的打开标志,否则,你得到的只不过是一串小的可怜的碎片。最简单的从网上下载文件,我们可以使用MFC的CInternetSession封装类,简单的用法如下:

CString strUrl = “http://hi.baidu.com/idealsoft/tools/test.exe”; //看好这个200K的exe文件

CInternetSession sess; //我建议大家对象全部用小写,感觉很实在,小而强大嘛!

CStdioFile* pFile = sess.OpenURL(strUrl); ASSERT(pFile);

我们照例还是获得pFile的大小,假如说是nlen,之所以我没有使用函数来获得,其实有我的苦衷,如果读者有兴趣的话,可以看MFC分类下的文章《CFile如何使用,用法举例》,反正,不管如何,假如我们现在已经获得这个网络文件的大小了,下面立即读取。

char* const _psz = new char[nlen + 1]; ASSERT(_psz);

unsigned int size = pFile->Read(_psz, nlen);

…… //好,现在文件已经获取了,干一些自己想干的事情

什么都没有干成!

开始查找原因,但什么都没有找到!

开始怀疑网络文件有问题!

开始怀疑MFC有问题!

开始怀疑VC有问题!

开始怀疑自己有问题!

的确有问题,问题在哪?我们先看看OpenURL的声明吧,源码始终是我们唯一可以依赖的!

CStdioFile* OpenURL(LPCTSTR pstrURL, DWORD dwContext = 1, DWORD dwFlags = INTERNET_FLAG_TRANSFER_ASCII, LPCTSTR pstrHeaders = NULL, DWORD dwHeadersLength = 0);

我们之前已经说过了,对于二进制文件的读取,一定要用二进制标志,CInternetSession也同样不能例外。

CStdioFile* pFile = pSession->OpenURL(pczUrl, 1, INTERNET_FLAG_TRANSFER_BINARY);

这才是正确的写法,而在OpenURL这个函数的声明中,pstrURL以后的参数都被赋予了默认值。再看dwFlags这个标志位,原来它默认的是ASCII码,也就是文本文件,可是我们要下载的,那是.exe文件,也就是二进制文件,所以好像搞错了,而对于这个函数的第二个参数dwContext,到底是什么意思?这不用你管,说实话,我也不太清楚,所以你想知道的,也是我想知道的,既然微软已经把它填了一个解释的连自己舌头都要绕断的默认值,那么我们也就随大溜吧,不过我这里可以先偷偷的告诉你,它的英文解释是:An application-defined value passed with the returned handle in callback,也就是:与回调中的返回句柄一同传递的一个应用程序定义的值!!!汗流浃背啊,不知所云,如果你想探个究竟,MSDN与源码正在恭候你。

好,切入主题。

这样一来,文件可以顺利下载了,一切都很令你满意,你开始有点得意的埋怨你刚刚的草率与鲁莽,因为一切都很正常。

这样的结果,已经能够令你满意,你现在要做的是:

…… //东搞一下,西搞一下

delete[] _psz; //释放堆内存

这样,大功告成了,你准备接受老板的赞赏,但得到的却是两个耳光!!

你愤恨,不满,准备离开这里。

真的大功告成了吗?其实是大失告败,现在,你一定会睁大眼睛,等待下文吧,对不起,我不是一个随便的人,虽然随便起来我不是人。

好,请您在《CFile如何使用,用法举例》中寻找答案。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值