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 循环

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

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

2. 数据读取和写入

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

    pInfo->wrFileSize += array.size();
    pInfo->wrFileOffset += array.size();
}
else {
    mDebug("file is free : " + pInfo->absolutePath);
    return;
}
  • 首先检查是否有有效的文件句柄 (file)。
  • 如果 file 有效,它从网络响应 (reply) 中最多读取 2MB 的数据并将其存储在 QByteArray 对象 array 中。
  • 然后,它将这些数据写入文件,并立即刷新文件以确保所有缓冲区的数据被写入磁盘。
  • 更新 pInfo 中的两个字段:
    • wrFileSize: 已经写入到文件的总大小。
    • wrFileOffset: 当前的写入偏移量。

3. 下载进度更新

DWORD tickCount = GetTickCount() >> 10; // 获取当前时间,以秒为单位

if ((tickCount != pInfo->tickCount) || (pInfo->wrFileSize == pInfo->fileSize)) {
    PNetworkInfo _pInfo = new(NetworkInfo);

    // 更新信息
    _pInfo->tickCount = pInfo->tickCount = tickCount;
    _pInfo->sendAddr = pInfo->recvAddr;
    _pInfo->absolutePath = pInfo->absolutePath;
    _pInfo->relativePath = pInfo->relativePath;
    _pInfo->fileSize = pInfo->fileSize;
    _pInfo->wrFileSize = pInfo->wrFileSize;
    _pInfo->wrFileOffset = pInfo->wrFileOffset;
    
	// 设置传输命令和类型
	_pInfo->_transCmd= PUSH_CMD;  
	_pInfo->_transType= PRGBAR_TYPE;

	pinfo -> wrFileOffset=0;

	ServerRecvFromNetworkListMutex.lock();  
	ServerRecvFromNetworkList.append(_pinfo);  
	ServerRecvFromNetworkListMutex.unlock();  
	ServerRecvFromNetworkListCond.wakeAll(); 
}
  • 使用 GetTickCount() 获取系统运行时间(以毫秒为单位),然后右移10位转换成秒数。
  • 检查是否经过了一秒钟(通过比较当前 tick count 和之前记录的值)或者是否已完成整个文件的下载(通过比较已写入的大小与预期文件大小)。
  • 如果条件满足,创建一个新的网络信息结构 _pINFO 并复制相关信息。
  • 将新的信息添加到一个共享列表 (ServerRecvFromNetworkList) 中,使用互斥锁进行同步,以保证线程安全,然后唤醒等待该列表条件变量的线程。

总结

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

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

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


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?