来自 HttpWebResponse 的 Stream 的字节数 return 不等于 ContentLength

The number of bytes return from HttpWebResponse's Stream doesn't equal to ContentLength

我正在使用 HttpWebRequestHttpWebResponseStream 创建下载管理器。首先,我在开始从流中读取文件内容之前从 HttpWebResponse 得到 ContentLength 并使用 while 循环停止读取,当它完成时(Stream.Read return 0,这意味着结束的流),我注意到我没有收到所有字节(我与 ContentLength 相比)

这是我用来从流中读取字节、计算内容长度(以兆字节为单位)、我收到的字节数(以兆字节为单位)以及我收到的字节百分比的一些代码。

                int maxReadSize = 102400;
                int readByte = 0;
                long downloadedSize = 0;
                int roundCount = 0;
                int byteCalRound = 0;
                byte[] buffer = new byte[maxReadSize];
                _currentFile.Status = DownloadStatus.Downloading;
                DateTime lastUpdate = DateTime.Now;

                do
                {
                    readByte = await _inStream.ReadAsync(buffer, 0, maxReadSize, _ct);
                    byteCalRound += readByte;
                    downloadedSize += readByte;
                    roundCount++;

                    if (roundCount == 5)
                    {
                        var now = DateTime.Now;
                        var interval = (now - lastUpdate).TotalSeconds;
                        var speed = (int)Math.Floor(byteCalRound / interval);
                        lastUpdate = now;
                        _currentFile.RecievedSize = downloadedSize;
                        _currentFile.Throughput = speed;
                        _currentFile.PercentProgress = downloadedSize;

                        byteCalRound = 0;
                        roundCount = 0;
                    }

                    await stream.WriteAsync(buffer, 0, readByte);
                } while (readByte != 0);
            }

            // Download completed
            _currentFile.Status = DownloadStatus.Complete;
            _currentFile.CompleteDate = DateTime.Now;

            ...

            // Calculate file size
            public double FileSize
            {
                get { return _fileSize; }
                set
                {
                    _fileSize = value / 1048576;
                }
            }

            // Calculate receive bytes
            public double RecievedSize
            {
                get { return _recievedSize; }
                set
                {
                    _recievedSize = value / 1048576;
                }
            }

            // Calculate percent
            public double PercentProgress
            {
                get { return _percentProgress; }
                set
                {
                    _percentProgress = value / 1048576 * 100 / _fileSize;
                }
            }

我一直在测试的结果(我下载的字节数)有时我收到了所有字节(我从 PercentProgressRecievedSize 中检查)和
有时我收到了 99.6-99.9% 的文件(我再次检查了 PercentProgressRecievedSize)所以,这就是我面临的问题。

所以,问题是什么导致了这个问题?

请注意,我只在一个网站上通过下载视频进行测试,因为我不认为这个问题只发生在这个网站上(我通常通过 Chrome 下载,结果是我收到 100文件的百分比。)

您正在阅读的数字(PercentProgressReceivedSize)仅在循环的每 5 次迭代中更新一次。如果有 12 次迭代,它们将反映前 10 次迭代的大小。

您可以在之后最后一次更新它们,即:

        ...
    } while (readByte != 0);
}

// Download completed
_currentFile.Status = DownloadStatus.Complete;
_currentFile.CompleteDate = DateTime.Now;
_currentFile.RecievedSize = downloadedSize;
_currentFile.PercentProgress = downloadedSize;

PS。如果您在团队中工作,请记住大多数人都希望 属性 returns 的 get 方法与上次 set 完全相同。