ホームページ  >  記事  >  バックエンド開発  >  C# の WebClient によって実装されたファイル ダウンロード コードの詳細なグラフィックとテキストの説明

C# の WebClient によって実装されたファイル ダウンロード コードの詳細なグラフィックとテキストの説明

黄舟
黄舟オリジナル
2017-03-07 11:45:392279ブラウズ

この記事では、C# での WebClient によるファイルのダウンロードの実装を中心に紹介します。編集者が非常に優れていると考えたので、参考として共有します。エディターをフォローして見てみましょう

さまざまな複雑なネットワーク環境を考慮して、作成者は、プログラムの使いやすさを高めるために、ダウンロードの試みに異なるプログラミング インターフェイスを使用することにしました。

ここではWebClientを使用する方法のみを紹介し、以降の記事で他の方法を紹介します。このブログ記事では主にアイデアとキーコードを紹介しており、完全なデモは記事の最後に添付されています。

プロキシを使用してインターネットにアクセスします

多くの会社員は、会社が設定したプロキシを介してインターネットにアクセスします。プロキシを介してインターネットにアクセスするのは、主に企業がさまざまな制御を実行しやすくするためです。もちろん、いくつかの特別な機能を実装することもできます...ただし、これにより、プログラムがネットワークにアクセスする際にいくつかの問題が発生します。

実際、WebClient の API はすでに非常に高性能です。たとえば、作成した HttpWebRequest オブジェクトには Proxy 属性があります。つまり、WebHttpRequest はデフォルトで、見つかったプロキシを使用します。これは素晴らしいもので、多くの状況に対処できます。ただし、このデフォルト プロキシがドメイン ユーザーの ID 情報を検証する必要がある場合、WebHttpRequest を使用してネットワークにアクセスすると失敗する可能性があります。この時点で、Proxy Credentials プロパティを確認すると、null であることがわかります。

システムのデフォルトの認証情報は WebClient API から取得できますが、Proxy.Credentials プロパティがデフォルトでこの値に設定されない理由は不明です。自分たちで設定するだけです。

request.Proxy.Credentials = CredentialCache.DefaultCredentials;

しかし、実際のネットワーク環境はより複雑である可能性があり、ユーザーはネットワーク用のプロキシとネットワークに必要な資格情報を指定する必要があります。文章は次のとおりです:

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 側のキャッシュ更新に関する問題が頻繁に見つかります。オンラインで検索しましたが、良い解決策は見つかりませんでしたが、リクエストにパラメータとしてランダムな文字列を追加するという良い回避策がありました。

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リクエストからダウンロードするファイルの長さを取得する必要があります。詳細については、これに添付されているデモを参照してください。記事。

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 の場合は、現在のダウンロードを終了します。

これで、ユーザーからの最も一般的な苦情が解決されました。実際、追加されたコードはそれほど多くなく、すべての知識ポイントは非常に微妙に見えます。しかし、明らかにユーザーエクスペリエンスが向上します。これは、主要な機能を完了することは作業の一部にすぎない場合もあり、常に経験と発見を必要とする場合があります...

デモのダウンロード アドレス: WebClientDemo_jb51.rar

。上記は、C# での WebClient 実装ファイルのダウンロード コードの詳細なグラフィックとテキストの説明です。さらに関連するコンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。