未知长度二进制流的读取

采用第三方工具处理网络流的时候,会面临一些问题,归纳如下:

1、二进制流的打开

很简单,使用popen、pclose即可。Windows平台下则采用_popen, _pclose。头文件都是stdio.h

例如:

//读取百度首页的文本流 FILE *fp = popen("curl www.baidu.com", "r");

2、二进制流的读取

依然很简单,使用大家都不陌生的fread就行啦~ 不过,这里有个trick:

fread的函数原型为:

/* * block_len: 表示每个结构的大小 * nitem: 结构个数。 nitem*block_len即为本次期望读取的字节数 * 返回值: 理想情况下四环nitem,即读入了多少个结构。不过问题也出在这里:如果期望读入的总数不是block_len的整数倍呢? * int fread(void *buf, int block_len, int nitem, FILE*fp);

这里,网友提供了一个很好的方法,并且进行了初步的评测:


"这个问题解决了,我将fread中第二个参数和第三个参数交换了以下位置,既:nReturn = fread(buf,1,1024,file); 这样,读取元素的长度为1字节,读取1024个元素,这样nReturn的值便是实际读取的字节数。这个想法受益于一个网友的帖子,提醒了我。
我测试过了,nReturn = fread(buf,1,1024,file)与nReturn = fread(buf,1024,1,file);在操在27087718字节长的二进制文件时,测试了150次,程序运行效率基本相同,前者比后者平均节省时间大约2ms。 "

通常我总是让nitem=1,所以返回值总是0或者1。为了获得真正读入的字节数,可以让block_len总是为1,nitem为期望读入的字节数。好方法!关于性能,可以再亲自测试一下。


3、获取二进制流的长度

基于2中的讨论,很容易获得二进制长度,例如:

while(!feof(fp)) { // 每次最多读入1024字节 len = fread(buf, 1, 1024, fp); // 注意,不是 // len = fread(buf, 1024, 1, fp); total += ret; printf("%s/n", buf); }

4、如何探测文件流结束

如3中所示,调用函数feof()咯~

以一个例子总结一下,该例子利用curl来读取baidu首页的二进制流并以1024字节为单位逐次打印到屏幕上:

#include <stdio.h> int main() { FILE *fp = NULL; int len = 0; int total = 0; char buf[1025]; //最后一个字节用于结束符 fp = _popen("curl www.baidu.com", "r"); //fp = _popen("dir", "r"); //fp = _popen("curl ftp://166.111.111.196/denied_ip.txt", "r"); if(!fp){ printf("wrong/n"); return 1; } while(!feof(fp)) { memset(buf, 0, 1025); // for simplicity len= fread(buf, 1, 1024, fp); total += len; printf("%s/n", buf); } printf("ftell=%d/n", total); _pclose(fp); }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值