CSDN-CSDN社区-VC/MFC-网络编程

收藏 [推荐] 【求助】文件传输断电续传的问题 100 不够再加 [问题点数:100,结帖人:ameyume]

  • ameyume
  • (雨夢)
  • 等 级:
  • 结帖率:
楼主发表于:2009-07-02 12:56:06
最近做一个项目,Client需要从服务器上面下载更新的文件(文件上百兆)。 设置了断点续传,经实际测试,client端突然断电 或者死机writefile 会造成下载的文件块很大一块都是空的 下次继续下载 就接着空的那一块末尾开始下。 最终造成下载的文件出错。
找了下这方面的资料,跟WINDOWS I/O缓存机制有关,读写文件的时候都丢进缓存了,而断电的时候正好没有写入.
解决的方案暂时想到二个
一 由于文件很大,不可能整个一个效验,断点续传的时候加入CRC32从文件末尾开始读1024*N的数据 到服务器上效验,直到正确为止。(算法很笨,遇到文件中很长一段为0的时候CRC32值正确,效验就出错了)
二 写IO驱动,拦截写入函数的操作做计数处理。(太复杂)
急求做过这方面的朋友给个完美解决方案。分不够在加  直到解决为止。
回复次数:41
#1楼 得分:1回复于:2009-07-02 13:06:22
每次定时写入磁盘, 并记录当前已写数据大小, 断电时, 可能刚好错过记录,这没关系, 最多下一次再重复读一次已写入(或没写入)的buffer
#2楼 得分:1回复于:2009-07-02 13:08:30
自己做一个记录喽。写入成功之后,再更新记录值。
这样即使是停电瞬间数据写入成功,但是记录值没有更新也无所谓。
  • Delphigis用户头像
  • Delphigis
  • (坚持 总结 阳光总在风雨后)
  • 等 级:
#3楼 得分:1回复于:2009-07-02 13:08:44
引用 1 楼 yjgx007 的回复: 每次定时写入磁盘, 并记录当前已写数据大小, 断电时, 可能刚好错过记录,这没关系, 最多下一次再重复读一次已写入(或没写入)的buffer


不错,原来我想说接多少写多少来着,呵呵,还是这样好
#4楼 得分:1回复于:2009-07-02 13:10:19
与1楼观点雷同了。
  • slek用户头像
  • slek
  • (slek)
  • 等 级:
  • 2

#5楼 得分:1回复于:2009-07-02 13:11:59
与1楼观点雷同了。
#6楼 得分:50回复于:2009-07-02 13:13:02
  • mengjj用户头像
  • mengjj
  • (世界在变)
  • 等 级:
#7楼 得分:2回复于:2009-07-02 13:15:50
很简单,如果停电了,下次写的时候你往前推个1k或1M来写,就啥问题都没有了.毕竟停电的事件还是不多的嘛.至于如何判断是否是停电(非正常关闭),还是正常退出,应该不难吧
#8楼 得分:0回复于:2009-07-02 14:03:06
引用 1 楼 yjgx007 的回复: 每次定时写入磁盘, 并记录当前已写数据大小, 断电时, 可能刚好错过记录,这没关系, 最多下一次再重复读一次已写入(或没写入)的buffer

关键就是怎么判断数据是否已经成功写入。  请问定时写入磁盘怎么做。  急求  感谢了
#9楼 得分:0回复于:2009-07-02 14:06:04
我现在的 流程是 createfile 共享模式打开  readbufer  然后 writefile  也考虑了mengjj往前推1K 或者1M的办法  但是遇到大文件的时候  有可能1-10M都是0 这样就出错了
请各位大大 继续提出好的方案  拜谢了。
  • Conry用户头像
  • Conry
  • (我笨善良)
  • 等 级:
#10楼 得分:30回复于:2009-07-02 14:27:09
#11楼 得分:0回复于:2009-07-02 14:32:02
引用 10 楼 Conry 的回复: FlushFileBuffers函数返回成功后再写记录

马上测试! 好用马上结贴
  • wuhuwy用户头像
  • wuhuwy
  • (勇者无畏)
  • 等 级:
#12楼 得分:1回复于:2009-07-02 14:54:57
引用楼主 ameyume 的帖子: 最近做一个项目,Client需要从服务器上面下载更新的文件(文件上百兆)。 设置了断点续传,经实际测试,client端突然断电 或者死机writefile 会造成下载的文件块很大一块都是空的 下次继续下载 就接着空的那一块末尾开始下。 最终造成下载的文件出错。 找了下这方面的资料,跟WINDOWS I/O缓存机制有关,读写文件的时候都丢进缓存了,而断电的时候正好没有写入. 解决的方案暂时想到二个 一 由于文件很大,不可能整个一个效验,…

顶!
#13楼 得分:5回复于:2009-07-02 14:55:40
老大不是有个 flush 函数吗? 你写入之后  flush 一下,然后在记录位置,, 不就没缓存会丢失的问题了。。。
#14楼 得分:0回复于:2009-07-02 15:53:30
引用 7 楼 mengjj 的回复: 很简单,如果停电了,下次写的时候你往前推个1k或1M来写,就啥问题都没有了.毕竟停电的事件还是不多的嘛.至于如何判断是否是停电(非正常关闭),还是正常退出,应该不难吧


这个不错
#15楼 得分:2回复于:2009-07-02 16:18:42
引用 6 楼 zzz3265 的回复: 写入文件指定不用缓冲FILE_FLAG_NO_BUFFERING, 写入成功再保存状态


我同意这个,设置了这个写进去就肯定写进去了.
#17楼 得分:1回复于:2009-07-02 17:01:36
ding xia
#18楼 得分:1回复于:2009-07-02 17:27:30
路过,帮顶
  • ytfsse用户头像
  • ytfsse
  • (无声的落幕)
  • 等 级:
#19楼 得分:1回复于:2009-07-02 17:38:45
不错,学习一下
#20楼 得分:0回复于:2009-07-02 17:43:02
  • xinming1558用户头像
  • xinming1558
  • (只为成功找方法,不为失败找借口)
  • 等 级:
#21楼 得分:0回复于:2009-07-02 18:07:52
来学习滴!
  • wenxy1用户头像
  • wenxy1
  • (周末了,极速飙车)
  • 等 级:
#22楼 得分:1回复于:2009-07-02 18:21:54
回退一个或多个分断嘛 。
#23楼 得分:0回复于:2009-07-02 19:43:44
学习一下
#24楼 得分:0回复于:2009-07-02 20:16:28
引用 3 楼 Delphigis 的回复: 引用 1 楼 yjgx007 的回复: 每次定时写入磁盘, 并记录当前已写数据大小, 断电时, 可能刚好错过记录,这没关系, 最多下一次再重复读一次已写入(或没写入)的buffer 不错,原来我想说接多少写多少来着,呵呵,还是这样好
可能你原来没有考虑断电吧
#25楼 得分:0回复于:2009-07-03 10:31:25
学习一下!
#26楼 得分:0回复于:2009-07-03 13:43:43
学习中
  • czylj用户头像
  • czylj
  • (夭夭)
  • 等 级:
#27楼 得分:0回复于:2009-07-03 15:01:35
1.定期flush,比如写入量超过64KB,就必须flush一次
2.启动后.回退2*64KB处,并从头取64KB对齐处可以下载.
#28楼 得分:0回复于:2009-07-03 21:46:26
与1楼观点雷同了。学习中
#29楼 得分:0回复于:2009-07-03 23:03:03
那样啊 ,学习哈
  • myjian用户头像
  • myjian
  • (嗷嗷叫的老马---思路啊思路.)
  • 等 级:
  • 2

#31楼 得分:0回复于:2009-07-04 02:10:36
个人建议:

买个UPS...............................

硬件环境的问题使用硬件解决最理想吧........

毕竟经常断电,硬盘也早晚挂,最终还是要解决断电问题的..........
#32楼 得分:0回复于:2009-07-04 03:37:08
我们肯定要用io缓存,因为要对下载的文件进行校验,而是要知道缓存的大小,没写进去的是buffer的size的 0空间,进行校验再进行此大小断点的重传!
  • zouhj2009用户头像
  • zouhj2009
  • (把握好每一夜(色狼族长))
  • 等 级:
#33楼 得分:0回复于:2009-07-04 08:26:48
关注中......
#34楼 得分:0回复于:2009-07-10 17:16:32
用WriteFileEx,注册回调函数,文件写入完成后会被调用
#35楼 得分:0回复于:2009-07-11 02:40:32
点对点多线程断点续传
#36楼 得分:0回复于:2009-07-11 13:01:58
看不懂啊……汗……
#37楼 得分:0回复于:2009-07-13 09:48:07
创建文件时,设定write-through标志
或者写一段,就flush一下
#38楼 得分:0回复于:2009-08-28 08:16:57
O
#39楼 得分:0回复于:2009-12-09 15:19:51
我觉得你先在磁盘写入数据,然后再在配置文件中记录上次写入数据的位置,这样就肯定能避免你的这中问题了。挺好办的,你现在肯定是先在配置文件中写入位置,然后在内容文件中写入数据吧。
还有你说的有很多都是0 的情况,很有可能是你在创建内容文件的时候没有把空文件用一些值填满
  • clever101用户头像
  • clever101
  • (好好学习,天天向上)
  • 等 级:
#40楼 得分:0回复于:2009-12-09 22:50:40
    学习!
#41楼 得分:0回复于:2009-12-09 23:11:07
太高深了,先打个基础。