前段时间写了一个多线程下载的程序,启动多个线程,每个线程负责下载一段程序,本地写的时候,先计算好offset,然后调用fseek移动文件指针,然后调fwrite就可以.

为了支持断点续传,在当前文件已经存在的情况下,使用fopen("xxx","ab")打开文件。结果发现文件内容经常的错位,折腾了好几天,开始怀疑网络传输,后面又怀疑多线程互斥没有做好.最后才找到原因:

FILE *fopen( const char *filename, const char *mode )的问题.

在MSDN里面有段说明

When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned using fseek, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.

正确的方法是用"rb+"打开已有文件,这样就可以随意的移动文件指针,实现随机写。

FlashGet采用多线程下载,本地会生成一个.jc!,而这个文件随着下载过程其大小会不断变化,直到文件下载成功.这个处理其实很简单,就是把文件分成固定大小的片进行下载,用 fseek-fwrite 的方式写数据,如过下载没有完成就停止了,那么生成可以一个临时的记录文件,以便断点续传。下面就是这个文件的伪码定义

struct FileRecord 
{
   int size; //文件大小
  int piece_num;//文件片的数量 
  int *m_cell;//new int[piece_num],用来存放每个文件片被下载了多少 

}


本文地址: http://lutaf.com/32.htm 鲁塔弗原创文章,欢迎转载,请附带原文链接