1 /// <summary> 2 /// 文件块大小为4M ( 如果文件总大小超过 _chunkSize 定义的大小,则把该文件切割成大小为 _chunkSize 的文件块分批下载 ) 3 /// </summary> 4 private int _chunkSize = 4 * 1024 * 1024; 5 6 /// <summary> 7 /// 已经下载的字节数 8 /// </summary> 9 private long _downloadedBytes = 0; 10 11 /// <summary> 12 /// 要下载的文件的总大小 13 /// </summary> 14 private long _length; 15 16 /// <summary> 17 /// 要下载的文件的地址 18 /// </summary> 19 public string Url = "http://localhost/Downloader/test.rar"; 20 21 /// <summary> 22 /// 获取文件大小 23 /// </summary> 24 private void GetFileSize() 25 { 26 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.Url); 27 request.BeginGetResponse(result => 28 { 29 HttpWebRequest req = (HttpWebRequest)result.AsyncState; 30 HttpWebResponse res = (HttpWebResponse)req.EndGetResponse(result); 31 this._length = res.ContentLength; 32 }, request); 33 } 34 35 private void BeginRequest() 36 { 37 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.Url); 38 request.Headers["Range"] = "bytes=" + this._downloadedBytes + "-" + (this._downloadedBytes + _chunkSize - 1); 39 request.BeginGetResponse(new AsyncCallback(ResponseCallBack), request); 40 } 41 42 private void ResponseCallBack(IAsyncResult result) 43 { 44 HttpWebRequest request = (HttpWebRequest)result.AsyncState; 45 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); 46 //this._lenght = response.ContentLength;// 这里获取的大小为当前请求的块大小 47 int count = 0; 48 using (System.IO.Stream stream = response.GetResponseStream()) 49 { 50 string savaName = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\test.rar"; 51 System.IO.FileMode mode = this._downloadedBytes > 0 ? System.IO.FileMode.Append : System.IO.FileMode.CreateNew; 52 using (System.IO.FileStream fileStream = System.IO.File.Open(savaName, mode)) 53 { 54 byte[] bytes = new byte[4096]; 55 int read; 56 while ((read = stream.Read(bytes, 0, bytes.Length)) != 0) 57 { 58 fileStream.Write(bytes, 0, read); 59 count += read; 60 } 61 } 62 } 63 this._downloadedBytes += count; 64 65 if (_downloadedBytes < this._length) 66 { 67 this.BeginRequest(); 68 } 69 }
我想利用Range Header做断点下载大文件,我怎么获取要下载的文件大小来显示进度条。添加了Range之后返回的ContentLength是请求到的文件碎片大小,我想获取整个文件的大小应该怎么做??自己定义了一个GetFileSize方法,但是貌似它会一次性把整个文件都下载下来。这样子的话,我分批下载就没意义了,请问有其他办法获取文件大小么?
解决了,使用HEAD方式请求。
1 WebRequest request = System.Net.Browser.WebRequestCreator.ClientHttp.Create(new Uri("http://localhost/Downloader/test.rar")); 2 request.Method = "HEAD"; 3 request.BeginGetResponse(result => 4 { 5 WebRequest req = (WebRequest)result.AsyncState; 6 WebResponse res = (WebResponse)req.EndGetResponse(result); 7 long length; 8 length = long.TryParse(res.Headers["Content-Length"], out length) ? length : 0; 9 }, request);
服务器单独写个方法返回文件的大小。
服务器?你的意思是说我不要直接请求这个rar文件,而是请求服务器的某个处理程序,把这个rar文件作为参数。然后服务器再获取这个rar的文件大小以及其他信息再返回到客户端Silverlight么?是这个意思么??但是如果这个文件不在这台服务器,在其他服务器呢?它可能在任何一个服务器。如果这样的话,这个问题只是转嫁给了服务器。