快速高效的更新程序

时间:2013-08-23 14:55:22

标签: c# performance

我正在为游戏客户端开发更新程序,以便玩家在更新时不必下载整个客户端。

现在,创建标准更新程序并不是很难,但是对于大文件来说它很慢。

客户端大约有1.5 GB未压缩,并且有大约250个文件。更新服务器上的文件是gzip压缩的,可以通过HTTP下载。

更新程序的工作方式如下:从服务器获取补丁列表 - >将补丁列表中的文件与本地文件进行比较(crc32 / filesize) - >如果丢失/错误的文件大小/散列不一样 - >从服务器下载gzip压缩文件 - >解压缩文件

更新程序中最耗时的部分:为每个文件/下载大文件生成crc32哈希

我想到了一些可以加快速度的事情:

  • 类似Rsync的diff更新程序 - 这会加快下载速度,因为它只能获取文件的不同部分而不只是下载整个文件。这会很有用,因为通常客户端更新不会影响大文件的许多部分。但我想这对于这个目的来说会有些过分。

  • 更好的压缩 - 当客户端被压缩时,Gzip可以节省大约200 MB。我没有尝试过使用其他一些压缩方法,但我猜bzip2,lzma还是可以节省更多空间并加快下载速度。具有讽刺意味的是,他们会减慢文件的解压缩速度。

  • 其他文件检查方法 - 目前我正在使用C#crc32实现,因为它比标准c#md5实现更快。是否有更快的算法可以判断文件是否相同?

  • 版本系统 - 它实际上不会加速任何东西,但更新程序不必计算所有哈希值。如果用户愿意,还可以使用额外的“修复”功能,根据实际版本检查所有文件。

我应该使用哪些解决方案,还是我没有列出任何我应该使用的方法呢?

3 个答案:

答案 0 :(得分:2)

压缩单个文件

您可以只下载新的或更改过的文件,而不是下载整个软件包。

在客户端和服务器上存储哈希

通过预先计算哈希值,您可以节省大量时间。您的哈希比较步骤变为单个文件的差异,该文件存储所有文件的哈希值。这在功能上与版本控制系统相同,但“版本”有点难以愚弄。用户可以轻松打开版本的纯文本文件,并将数字设置为下一个版本以跳过补丁。如果你想防止这种行为,哈希稍微更安全。

并行化

执行哈希文件的差异后,您可以将请求发送到服务器以获取需要下载的文件列表。然后,您的下载程序可以连续流式传输每个文件,并且在收到它们时,其他线程可以解压缩并移动下载的文件。

答案 1 :(得分:1)

我过去做过这个,这取决于你的具体实施和期望的选择。我们做过的一些事情:

  • 允许用户选择“完整”扫描的首选项以进行每次更新。除非存在一些安全问题,否则您没有理由比较每个哈希值。
  • 在完整扫描时,如果需要,请将哈希首先执行到纯文本文档或XML文档。我发现XML可以帮助匹配服务器,只检索必要的特定文件。
  • 如果这对你有用,你总是可以只对文件的“名称”而不是内容执行哈希。我的意思是什么?散列Directory.GetFiles()结果与预期结果,以查看是否需要进一步潜水以查找丢失的文件。如果您担心文件被篡改并且实际上需要内容的哈希值,这显然是行不通的。

答案 2 :(得分:1)

另一个选择是存储已更改内容的增量而不是完整文件。然后,您只需要将文件“升级”到新版本所需的内容。查看http://xdelta.org/