免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6411 | 回复: 15

[C] 自己写的函数进行拷贝/上传文件,部分文件副本会损坏是什么原因 [复制链接]

论坛徽章:
26
CU大牛徽章
日期:2013-03-13 15:15:08水瓶座
日期:2014-08-31 19:44:01卯兔
日期:2014-09-05 08:48:33摩羯座
日期:2014-09-07 13:03:35子鼠
日期:2014-09-10 08:42:36白羊座
日期:2014-09-20 12:39:07丑牛
日期:2014-09-24 07:35:252015年亚洲杯之阿联酋
日期:2015-02-03 17:42:542015年亚洲杯之卡塔尔
日期:2015-02-11 13:13:022015年亚洲杯之约旦
日期:2015-03-03 15:10:522015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之卡塔尔
日期:2015-03-27 14:08:09
发表于 2013-07-28 17:45 |显示全部楼层
有点奇怪,用下面的模式进行文件拷贝,某些文件的拷贝的副本与原文件md5不一样,为什么?下面是我的测试代码功能是拷贝一个文件。之所以是用readline按行读取是因为有些协议如HTTP、 FTP是基于行的需要按行读取。

  1. rc = readline(fd1,buf,MAXLINE);
  2.     while(rc > 0)
  3.     {
  4.         wn = writen(fd2,buf,rc);
  5.         rc = readline(fd1,buf,MAXLINE);
  6.     }
  7.     close
复制代码
readline是自己写的函数调用read,碰到\n或文件读取完毕就返回,如果read发生错误且是EINTR错误则继续读取否则就返回 。不带缓冲效率很低。我总共写了带缓冲和不带缓冲两个版本均是同样的问题。

  1. ssize_t writen(int fd,const void*vptr,size_t n)
  2. {
  3.     size_t nleft;
  4.     ssize_t nwriten;
  5.     const char *ptr;
  6.     ptr = vptr;
  7.     nleft = n;
  8.     while(nleft > 0)
  9.     {
  10.         if (( nwriten = write(fd,ptr, nleft)) <= 0)
  11.         {
  12.             if (nwriten < 0 && errno == EINTR)
  13.                 nwriten = 0;
  14.             else
  15.                 return -1;
  16.         }
  17.         nleft -= nwriten;
  18.         ptr += nwriten;
  19.     }
  20.     return n;
  21. }
复制代码
发生拷贝损坏的是部分二进制文件。我现在需要分析一些协议如HTTP所以需要按行读取数据。上面的代码是我用于进行测试本地拷贝文件的。
谁能告诉我为什么会部分文件拷贝的副本md5值和原文件的不一样

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
发表于 2013-07-29 08:21 |显示全部楼层
比较一下文件的区别嘛,比如是否是 \r\n 和 \n

论坛徽章:
26
CU大牛徽章
日期:2013-03-13 15:15:08水瓶座
日期:2014-08-31 19:44:01卯兔
日期:2014-09-05 08:48:33摩羯座
日期:2014-09-07 13:03:35子鼠
日期:2014-09-10 08:42:36白羊座
日期:2014-09-20 12:39:07丑牛
日期:2014-09-24 07:35:252015年亚洲杯之阿联酋
日期:2015-02-03 17:42:542015年亚洲杯之卡塔尔
日期:2015-02-11 13:13:022015年亚洲杯之约旦
日期:2015-03-03 15:10:522015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之卡塔尔
日期:2015-03-27 14:08:09
发表于 2013-07-29 10:47 |显示全部楼层
回复 2# bruceteen
二进制文件啊,不好比较


   

论坛徽章:
36
CU大牛徽章
日期:2013-09-18 15:24:20NBA常规赛纪念章
日期:2015-05-04 22:32:03牛市纪念徽章
日期:2015-07-24 12:48:5515-16赛季CBA联赛之辽宁
日期:2016-03-30 09:26:4715-16赛季CBA联赛之北控
日期:2016-03-30 11:26:2315-16赛季CBA联赛之广夏
日期:2016-05-20 15:46:5715-16赛季CBA联赛之吉林
日期:2016-05-24 11:38:0615-16赛季CBA联赛之青岛
日期:2016-05-30 13:41:3215-16赛季CBA联赛之同曦
日期:2016-06-23 16:41:052015年亚洲杯之巴林
日期:2015-02-03 15:05:04CU大牛徽章
日期:2013-09-18 15:24:52CU十二周年纪念徽章
日期:2013-10-24 15:46:53
发表于 2013-07-29 12:42 |显示全部楼层
本帖最后由 idi0t 于 2013-07-29 12:44 编辑

回复 3# Third-Edition


    用工具啊,md5值不一样的原因有几种吧,先看看文件大小是不是一样(比如说忘记fflush,或者你一次读一行,会不会最后没换行符),如果一样再比较哪里不一样.

论坛徽章:
26
CU大牛徽章
日期:2013-03-13 15:15:08水瓶座
日期:2014-08-31 19:44:01卯兔
日期:2014-09-05 08:48:33摩羯座
日期:2014-09-07 13:03:35子鼠
日期:2014-09-10 08:42:36白羊座
日期:2014-09-20 12:39:07丑牛
日期:2014-09-24 07:35:252015年亚洲杯之阿联酋
日期:2015-02-03 17:42:542015年亚洲杯之卡塔尔
日期:2015-02-11 13:13:022015年亚洲杯之约旦
日期:2015-03-03 15:10:522015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之卡塔尔
日期:2015-03-27 14:08:09
发表于 2013-07-29 12:59 |显示全部楼层
回复 4# idi0t
我用gdb调试,可以明确的确定是我的readline函数有多/少读少量数据(很小几个字节到几十个字节),导致了部分二进制文件的大小与原文件不一致,我都把自己写readline函数换成了unp《unix网络编程》里提供的readline函数还是一样,难道是文件内容比较特殊我没注意到

   

论坛徽章:
36
CU大牛徽章
日期:2013-09-18 15:24:20NBA常规赛纪念章
日期:2015-05-04 22:32:03牛市纪念徽章
日期:2015-07-24 12:48:5515-16赛季CBA联赛之辽宁
日期:2016-03-30 09:26:4715-16赛季CBA联赛之北控
日期:2016-03-30 11:26:2315-16赛季CBA联赛之广夏
日期:2016-05-20 15:46:5715-16赛季CBA联赛之吉林
日期:2016-05-24 11:38:0615-16赛季CBA联赛之青岛
日期:2016-05-30 13:41:3215-16赛季CBA联赛之同曦
日期:2016-06-23 16:41:052015年亚洲杯之巴林
日期:2015-02-03 15:05:04CU大牛徽章
日期:2013-09-18 15:24:52CU十二周年纪念徽章
日期:2013-10-24 15:46:53
发表于 2013-07-29 13:06 |显示全部楼层
回复 5# Third-Edition


    不懂,readline的话我在想,要是二进制文件该如何读取,如果仅是为了复制文件,读一行真没啥用啊

论坛徽章:
26
CU大牛徽章
日期:2013-03-13 15:15:08水瓶座
日期:2014-08-31 19:44:01卯兔
日期:2014-09-05 08:48:33摩羯座
日期:2014-09-07 13:03:35子鼠
日期:2014-09-10 08:42:36白羊座
日期:2014-09-20 12:39:07丑牛
日期:2014-09-24 07:35:252015年亚洲杯之阿联酋
日期:2015-02-03 17:42:542015年亚洲杯之卡塔尔
日期:2015-02-11 13:13:022015年亚洲杯之约旦
日期:2015-03-03 15:10:522015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之卡塔尔
日期:2015-03-27 14:08:09
发表于 2013-07-29 13:25 |显示全部楼层
回复 6# idi0t
是这样的,数据内容如下
  1. -----------------------xxxxx\r\n二进制文件内容\r\n-----------------------xxxxx\r\n
复制代码
由于数据格式如上面所示,所以必须把数据按行读取然后判断是否到边界了,二进制文件内容被“-----------------------xxxxx\r\n”包围。



   

论坛徽章:
278
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2013-07-29 13:49 |显示全部楼层
Third-Edition 发表于 2013-07-29 13:25
回复 6# idi0t
是这样的,数据内容如下由于数据格式如上面所示,所以必须把数据按行读取然后判断是否到边 ...


你这文件格式设计本身就有缺陷,怎么保证二进制内容中没有你的起始、结束行?

论坛徽章:
26
CU大牛徽章
日期:2013-03-13 15:15:08水瓶座
日期:2014-08-31 19:44:01卯兔
日期:2014-09-05 08:48:33摩羯座
日期:2014-09-07 13:03:35子鼠
日期:2014-09-10 08:42:36白羊座
日期:2014-09-20 12:39:07丑牛
日期:2014-09-24 07:35:252015年亚洲杯之阿联酋
日期:2015-02-03 17:42:542015年亚洲杯之卡塔尔
日期:2015-02-11 13:13:022015年亚洲杯之约旦
日期:2015-03-03 15:10:522015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之卡塔尔
日期:2015-03-27 14:08:09
发表于 2013-07-29 14:15 |显示全部楼层
回复 8# hellioncu
这个不是我设计的,这个是http协议里面规定的传送文件的格式,详情请看:rfc2616和rfc1867 http://www.ietf.org/rfc/rfc1867.txt


   

论坛徽章:
26
CU大牛徽章
日期:2013-03-13 15:15:08水瓶座
日期:2014-08-31 19:44:01卯兔
日期:2014-09-05 08:48:33摩羯座
日期:2014-09-07 13:03:35子鼠
日期:2014-09-10 08:42:36白羊座
日期:2014-09-20 12:39:07丑牛
日期:2014-09-24 07:35:252015年亚洲杯之阿联酋
日期:2015-02-03 17:42:542015年亚洲杯之卡塔尔
日期:2015-02-11 13:13:022015年亚洲杯之约旦
日期:2015-03-03 15:10:522015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之卡塔尔
日期:2015-03-27 14:08:09
发表于 2013-07-29 14:19 |显示全部楼层
回复 8# hellioncu
很多协议如HTTP FTP都是基于行的,但是HTTP比较蛋疼,包含了二进制所以要根据这个分界符来截取文件。我就是这里出现了问题,我可以确定我读取到了这个分界符,但是之间的二进制内容我未完整的接收下来,很奇怪。部分文件无法完整接收完毕。

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。




----------------------------------------

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP