ZBLOG

do { if (file) {/***************************************** ** the max cache size is 2Mb per read ** ** 2097152 = 2 * 1024 * 1024 (2Mb) ** *****************************************/ QByteArray array = reply->read(2097152); ...

这段代码是一个循环,用于从某个网络响应(reply)中读取数据并写入到文件中,同时更新下载进度。以下是对每一部分的详细分析:

1. do-while 循环

  1. do {
  2. ...
  3. } while (reply->size());

这个循环会持续执行,直到 reply->size() 返回 0,表示没有更多的数据可以读取。

2. 数据读取和写入

  1. if (file) {
  2. /*****************************************
  3. ** the max cache size is 2Mb per read **
  4. ** 2097152 = 2 * 1024 * 1024 (2Mb) **
  5. *****************************************/
  6. QByteArray array = reply->read(2097152);
  7. file->write(array);
  8. file->flush();
  9. pInfo->wrFileSize += array.size();
  10. pInfo->wrFileOffset += array.size();
  11. }
  12. else {
  13. mDebug("file is free : " + pInfo->absolutePath);
  14. return;
  15. }
  • 首先检查是否有有效的文件句柄 (file)。
  • 如果 file 有效,它从网络响应 (reply) 中最多读取 2MB 的数据并将其存储在 QByteArray 对象 array 中。
  • 然后,它将这些数据写入文件,并立即刷新文件以确保所有缓冲区的数据被写入磁盘。
  • 更新 pInfo 中的两个字段:
    • wrFileSize: 已经写入到文件的总大小。
    • wrFileOffset: 当前的写入偏移量。

3. 下载进度更新

  1. DWORD tickCount = GetTickCount() >> 10; // 获取当前时间,以秒为单位
  2. if ((tickCount != pInfo->tickCount) || (pInfo->wrFileSize == pInfo->fileSize)) {
  3. PNetworkInfo _pInfo = new(NetworkInfo);
  4. // 更新信息
  5. _pInfo->tickCount = pInfo->tickCount = tickCount;
  6. _pInfo->sendAddr = pInfo->recvAddr;
  7. _pInfo->absolutePath = pInfo->absolutePath;
  8. _pInfo->relativePath = pInfo->relativePath;
  9. _pInfo->fileSize = pInfo->fileSize;
  10. _pInfo->wrFileSize = pInfo->wrFileSize;
  11. _pInfo->wrFileOffset = pInfo->wrFileOffset;
  12. // 设置传输命令和类型
  13. _pInfo->_transCmd= PUSH_CMD;
  14. _pInfo->_transType= PRGBAR_TYPE;
  15. pinfo -> wrFileOffset=0;
  16. ServerRecvFromNetworkListMutex.lock();
  17. ServerRecvFromNetworkList.append(_pinfo);
  18. ServerRecvFromNetworkListMutex.unlock();
  19. ServerRecvFromNetworkListCond.wakeAll();
  20. }
  • 使用 GetTickCount() 获取系统运行时间(以毫秒为单位),然后右移10位转换成秒数。
  • 检查是否经过了一秒钟(通过比较当前 tick count 和之前记录的值)或者是否已完成整个文件的下载(通过比较已写入的大小与预期文件大小)。
  • 如果条件满足,创建一个新的网络信息结构 _pINFO 并复制相关信息。
  • 将新的信息添加到一个共享列表 (ServerRecvFromNetworkList) 中,使用互斥锁进行同步,以保证线程安全,然后唤醒等待该列表条件变量的线程。

总结

这段代码实现了一个简单的下载处理逻辑,其中:

  • 从网络获取数据并保存到本地文件。
  • 每次成功读写后更新下载进度,并在合适时机通知其他组件或线程关于当前下载状态的信息。

需要注意的是,为了避免内存泄漏,应确保适当释放分配给 _PINFO 的内存。此外,该代码假设多个线程可能同时访问共享列表,因此使用互斥锁和条件变量来保护访问是一种常见做法。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20036

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?