文件已下载量/总大小计算异常:数值始终显示0的技术求助
下载进度MB显示始终为0的问题解决
问题原因
e.BytesReceived和e.TotalBytesToReceive是整数类型,当文件大小或已下载量小于1MB(1024×1024=1048576字节)时,直接除以1024.0/1024.0得到的是小于1的小数,Math.Round()会将其舍入为0,导致显示0 MB。
比如你提供的示例值:
- 2196字节 ÷ 1048576 ≈ 0.0021 MB,Round后为0
- 194899字节 ÷ 1048576 ≈ 0.185 MB,Round后为0
解决方法
方法1:保留小数位数
修改downloadedMBs和totalMBs的计算逻辑,指定Math.Round()的小数位数,让小数值能正确显示:
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e, Stopwatch sw) { string downloadProgress = e.ProgressPercentage + "%"; string downloadSpeed = string.Format("{0} MB/s", (e.BytesReceived / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds).ToString("0.00")); // 保留2位小数 string downloadedMBs = Math.Round(e.BytesReceived / 1024.0 / 1024.0, 2) + " MB"; string totalMBs = Math.Round(e.TotalBytesToReceive / 1024.0 / 1024.0, 2) + " MB"; string progress = $"{downloadedMBs}/{totalMBs} ({downloadProgress}) @ {downloadSpeed}"; lblDownloadProgress.Text = progress; textProgressBar1.Value = e.ProgressPercentage; textProgressBar1.CustomText = progress; }
修改后示例值会显示为0.00 MB和0.19 MB,准确反映实际大小。
方法2:动态切换文件单位(推荐)
编写一个辅助方法,根据文件大小自动切换字节、KB、MB等单位,让显示更直观:
// 辅助方法:格式化文件大小为易读单位 private string FormatFileSize(long bytes) { string[] units = { "B", "KB", "MB", "GB" }; double size = bytes; int unitIndex = 0; while (size >= 1024 && unitIndex < units.Length - 1) { size /= 1024; unitIndex++; } return $"{Math.Round(size, 2)} {units[unitIndex]}"; } // 修改后的事件处理方法 private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e, Stopwatch sw) { string downloadProgress = e.ProgressPercentage + "%"; string downloadSpeed = string.Format("{0} MB/s", (e.BytesReceived / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds).ToString("0.00")); string downloadedSize = FormatFileSize(e.BytesReceived); string totalSize = FormatFileSize(e.TotalBytesToReceive); string progress = $"{downloadedSize}/{totalSize} ({downloadProgress}) @ {downloadSpeed}"; lblDownloadProgress.Text = progress; textProgressBar1.Value = e.ProgressPercentage; textProgressBar1.CustomText = progress; }
修改后示例值会显示为2.14 KB和190.33 KB,小文件场景下更友好。
方法3:向上取整(不推荐)
如果必须显示MB单位且不想出现0,可以用Math.Ceiling()向上取整,但会存在精度误差:
string downloadedMBs = Math.Ceiling(e.BytesReceived / 1024.0 / 1024.0) + " MB"; string totalMBs = Math.Ceiling(e.TotalBytesToReceive / 1024.0 / 1024.0) + " MB";
这种方式会把任何小于1MB的数值都显示为1 MB,仅适合对精度要求极低的场景。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

