鉴于种种庞杂的收集环境,笔者决议采纳差别的编程接口举行下载尝试,以增添顺序的可用性。
这里仅引见运用 WebClient 的要领,后续的文章会引见其他的要领。博文中重要引见思绪和症结代码,完全的 demo 附在文末。
运用代办接见收集
许多公司的员工都是经由历程公司设置的代办上网的。经由历程代办上网重假如轻易公司举行种种的控制,固然也能完成一些特别的功用… 不过这会给我们的顺序接见收集带来一些题目。
实在,WebClient 中的 API 已很智能了,比方我们建立的 HttpWebRequest 对象,它自带一个 Proxy 属性。也就是说,WebHttpRequest 默许会运用找到的代办。这很棒,也能处置惩罚许多状况了。但是假如这个默许的代办须要考证域用户的身份信息,这时刻运用 WebHttpRequest 接见收集就能够失利。此时检察 Proxy. Credentials 属性,发明它是 null。
从 WebClient 的 API 中是能够取到体系默许的 Credentials 的,只是不太清晰为何 Proxy.Credentials 属性默许没有设置为这个值。我们本身设置下就能够了。
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
但现实的收集环境能够会更庞杂,须要用户来指定联网的代办,并同时指定联网所需的 Credentials。写法以下:
myProxy = new WebProxy("proxyAddress"); myProxy.Credentials = new NetworkCredential(ProxyUserName, ProxyUserPasswd, DomainName);
战胜缓存
缓存可谓无处不再,在服务器端 CDN 会有缓存,在客户端的代办层也会有缓存。所以常常出现的题目是:服务器上的文件显著更新了,照样会有一些客户下载到旧文件。我们先来处置惩罚客户端的缓存题目。
HttpWebRequest 的 CachePolicy.Level 属性就是设置缓存战略的,只是它的默许值是 BypassCache。我们把它改成 Reload 就好了:
复制代码 代码以下:
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Reload);
接下来是服务器端的缓存题目。
如今人人彷佛都在运用 CDN,可在运用中常常发明 CDN 端的缓存更新有题目。在网上查了查也没有什么好的解决办法,不过却是有一个很好的 workaround,就是在请求中增加一个随机的字符串作为参数。
Random rdm = new Random(); string s = rdm.Next().ToString(); myUrl += "?" + s;
须要注重的是,关于缓存,一定要运用相符当前用例的战略,且不可搞一刀切。
更友爱的下载历程
运用滚动条显现下载进度,显现及时的下载速率,许可用户作废下载:
下面是下载用的中心代码,我们把它分为盘算下载百分比和盘算当前下载速率离别引见。
// 取得下载文件的长度 double contentLength = DownloadManager.GetContentLength(myHttpWebClient); byte[] buffer = new byte[BufferSize]; long downloadedLength = 0; long currentTimeSpanDataLength = 0; int currentDataLength; while ((currentDataLength = stream.Read(buffer, 0, BufferSize)) > 0 && !this._cancelDownload) { fileStream.Write(buffer, 0, currentDataLength); downloadedLength += (long)currentDataLength; currentTimeSpanDataLength += (long)currentDataLength; int intDownloadSpeed = 0; if (this._downloadStopWatch.ElapsedMilliseconds > 800) { double num5 = (double)currentTimeSpanDataLength / 1024.0; double num6 = (double)this._downloadStopWatch.ElapsedMilliseconds / 1000.0; double doubleDownloadSpeed = num5 / num6; intDownloadSpeed = (int)Math.Round(doubleDownloadSpeed, 0); this._downloadStopWatch.Reset(); this._downloadStopWatch.Start(); currentTimeSpanDataLength = 0; } double doubleDownloadPersent = 0.0; if (contentLength > 0.0) { doubleDownloadPersent = (double)downloadedLength / contentLength; } }
在下载的历程当中盘算下载百分比
起首须要从 http 请求中取得要下载文件的长度,细节请参考本文所配 demo。
double contentLength = DownloadManager.GetContentLength(myHttpWebClient);
每从文件流中读取一次数据,我们晓得读了若干个字节(currentDataLength),累计下来就是当前已下载了的文件长度。
downloadedLength += (long)currentDataLength;
然后做个除法就好了:
doubleDownloadPersent = (double)downloadedLength / contentLength;
盘算及时的下载速率
关于当前的下载速率,我们盘算过去的一段时刻内下载下来的字节数。时刻段能够运用 StopWatch 来取得,我挑选的时刻段请求大于 800 毫秒。
if (this._downloadStopWatch.ElapsedMilliseconds > 800) { /***********************************/ // 盘算上一个时刻段内的下载速率 double num5 = (double)currentTimeSpanDataLength / 1024.0; double num6 = (double)this._downloadStopWatch.ElapsedMilliseconds / 1000.0; double doubleDownloadSpeed = num5 / num6; /***********************************/ intDownloadSpeed = (int)Math.Round(doubleDownloadSpeed, 0); // 本次网速盘算完成后重置时刻计时器和数据计数器,最先下次的盘算 this._downloadStopWatch.Reset(); this._downloadStopWatch.Start(); currentTimeSpanDataLength = 0; }
事实上每次盘算下载速率的时刻段长度是不顾定的,但这并不影响盘算结果,我只需保证间隔上次盘算超过了 800 毫秒就好了。
许可用户作废下载
关于一个实行时刻比较长的使命来讲,不许可用户作废它是被切齿腐心的!尤其是网速不太好的时刻。所以我们须要给用户一个挑选:能够愉快(而不是痛楚)的完毕当前的路程。
而这统统对我们来讲又是那末的简朴!
代码以下:
while ((currentDataLength = stream.Read(buffer, 0, BufferSize)) > 0 && !this._cancelDownload){}
当从数据流中读取数据时,我们搜检用户是否是按下了"作废"按钮,就是这里的 this._cancelDownload 变量。假如它是 true 就完毕当前的下载。
至此,把用户埋怨最多的几个点都搞定了。实在也没有增添若干代码,而且每一个知识点看起来都是那末的纤细。但很显著的提高了用户的运用体验。这也给我们带来了一些启示,完成重要功用能够只是事情中的一部分,别的的一些事情能够并非那末显著,须要我们不停的体味,觉察…
Demo 下载地点:WebClientDemo_jb51.rar
以上就是C#中WebClient完成文件下载代码图文详解的内容,更多相关内容请关注ki4网(www.ki4.cn)!