通过Stream.Read下载文件时出现了ArgumentOutOfRangeException异常

5

在使用Silverlight下载非常大的文件(>2GB)时,我遇到了一个问题。我的应用程序是一个带有提升权限的离线下载管理器。

当文件达到一定数量的数据(2GB)时,会抛出以下异常:

System.ArgumentOutOfRangeException was caught
  Message=Specified argument was out of the range of valid values.
Parameter name: count
  StackTrace:
   in MS.Internal.InternalNetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   in MS.Internal.InternalNetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   in MySolution.DM.Download.BeginResponseCallback(IAsyncResult ar)
  InnerException: 
Null

我唯一的线索是这个网站,它展示了BeginCode的实现。只有当count小于0时,才会出现此异常。 我的代码:
/* "Target" is a File object. "source" is a Stream object */

var buffer = new byte[64 * 1024];
int bytesRead;
Target.Seek(0, SeekOrigin.End); // The file might exists when resuming a download

/* The exception throws from inside "source.Read" */
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
    Target.Write(buffer, 0, bytesRead);
    _fileBytes = Target.Length;
    Deployment.Current.Dispatcher.BeginInvoke(() => { DownloadPercentual = Double.Parse(Math.Round((decimal)(_fileBytes / (_totalSize / 100)), 5).ToString()); });
}

Target.Close();
logFile.Close();

错误发生在不同类型的文件上,它们来自于Amazon S3上的公共存储区,并通过常规的http请求获取。

source 是一个 Stream 对象。我会澄清的,谢谢! - Dorival
另外,_fileBytes 的类型是什么? - Cᴏʀʏ
_fileBytes 是应该下载的文件的总大小。这部分代码仅用于显示下载进度。它是一个 double 类型。 - Dorival
2
因此,偏移参数是Int32(有符号的,因此最大值为2 ^ 31-1),问题发生在约2 GB的文件大小处。 2 GB大约是2 ^ 31字节,对吧?巧合吗? - Anssssss
如果我正确理解AllowReadStreamBuffering,它会在调用回调函数之前将整个文件加载到内存中。由于你正在处理2GB以上的文件,这可能需要一段时间,并且可能不是一个好的解决方案。 - Badaro
显示剩余6条评论
1个回答

1

我搜索了一下,似乎这是Silverlight中已知的限制。一个可能的解决方法是使用Range头在多个小于2GB的部分中执行下载。


这个链接解释了如何在.NET 3.5上请求特定字节范围的多部分下载:https://dev59.com/aVjUa4cB1Zd3GeqPVudP对于4.0,只需指定:req.Headers[HttpRequestHeader.Range] = "bytes=500-999";其中req是一个HttpWebRequest类。 - Dorival

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接