|
.NET TIPS
ファイルのダウンロードをレジューム(再開)するには?[C#、VB]
デジタルアドバンテージ 遠藤 孝信
2008/02/21 |
|
|
現在多くのWebサーバでは、ファイルをダウンロードする際にダウンロードの開始位置を指定できるようになっている。この機能を使えば、何らかの理由で中断してしまったファイルのダウンロードを、中断した位置からレジューム(再開、リジューム)することができる。本稿では、そのコーディング方法について解説する。
HttpWebRequest/HttpWebResponseクラスによるダウンロード
ここではまず、HttpWebRequest/HttpWebResponseクラス(ともにSystem.Net名前空間)を使用して通常のダウンロード(新規ダウンロード)を行うコードを示す。HttpWebRequest/HttpWebResponseクラスの基本的な使い方については「TIPS:WebRequest/WebResponseクラスでWebページを取得するには?」を参照してほしい。
このDownloadメソッドは、第1パラメータで指定されたURLのファイルをダウンロードし、第2パラメータで指定されたファイルに書き込む。
using System;
using System.IO;
using System.Net;
public class WebUtil {
public static void Download(string url, string file) {
// リクエストの作成
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
// レスポンスの取得
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (FileStream fs = new FileStream(file, FileMode.Create)) {
using (Stream st = res.GetResponseStream()) {
Byte[] buf = new Byte[1024];
int count = 0;
do {
count = st.Read(buf, 0, buf.Length);
fs.Write(buf, 0, count);
} while (count != 0);
}
}
res.Close();
}
}
|
Imports System
Imports System.IO
Imports System.Net
Public Class WebUtil
Public Shared Sub Download(ByVal url As String, ByVal file As String)
' リクエストの作成
Dim req As HttpWebRequest _
= CType(WebRequest.Create(url), HttpWebRequest)
' レスポンスの取得
Dim res As HttpWebResponse _
= CType(req.GetResponse(), HttpWebResponse)
Using st As Stream = res.GetResponseStream()
Using fs As New FileStream(file, FileMode.Create)
Dim buf(1024) As Byte
Dim count As Integer = 0
Do
count = st.Read(buf, 0, buf.Length)
fs.Write(buf, 0, count)
Loop While count <> 0
End Using
End Using
res.Close()
End Sub
End Class
|
|
ファイルのダウンロードを行うDownloadメソッド(上:C#、下:VB) |
ダウンロードのレジュームは、これに若干のコードを追加することで可能だ。
AddRangeメソッドによるダウンロード範囲の指定
Webサーバに対してダウンロードする範囲を指定するには、リクエスト(=HttpWebRequestオブジェクト)に対してAddRangeメソッドを呼び出して行う。AddRangeメソッドではパラメータとして、ダウンロードを開始する位置を指定できる。
ダウンロードをレジュームする手順としては、途中までダウンロード済みのファイルのサイズを取得し、その値を開始位置としてダウンロードを行い、それにより取得したデータをそのファイルの末尾に追記していけばよい。
次のサンプル・プログラムはこれを実装したもので、ダウンロードするファイルのURLと、途中までダウンロード済みのファイルのパス名をコマンドライン引数で指定して実行すれば、ファイルの続き部分のダウンロードが開始される。
// resumedown.cs
using System;
using System.IO;
using System.Net;
public class WebUtil {
static void Main(string[] args) {
if (args.Length != 2) {
return;
}
string url = args[0];
string fileName = args[1];
long startPos = 0;
// ファイルがすでに存在する場合、
// ファイルのサイズを取得する
if (File.Exists(fileName)) {
FileInfo info = new FileInfo(fileName);
startPos = info.Length;
}
WebRequest.DefaultWebProxy = null; // プロキシを使用しない
ResumeDownload(url, fileName, startPos);
}
public static bool ResumeDownload(
string url, string file, long startPos) {
Console.WriteLine("開始位置:" + startPos);
// リクエストの作成
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.AddRange((int)startPos); // ダウンロード開始位置を設定
// レスポンスの取得
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
if (res.StatusCode != HttpStatusCode.PartialContent) {
// レジュームに対応してない場合
res.Close();
return false;
}
using (FileStream fs = new FileStream(
file, FileMode.OpenOrCreate)) {
fs.Seek(0, SeekOrigin.End); // 末尾に追記
using (Stream st = res.GetResponseStream()) {
Byte[] buf = new Byte[1024];
int count = 0;
do {
count = st.Read(buf, 0, buf.Length);
fs.Write(buf, 0, count);
} while (count != 0);
}
res.Close();
}
return true;
}
}
// コンパイル方法:csc resumedown.cs
// 実行方法:resumedown.exe <URL> <保存先のファイル名>
|
|
ダウンロードのレジュームを行うC#のサンプル・プログラム(resumedown.cs) |
|
' resumedown.vb
Imports System
Imports System.IO
Imports System.Net
Public Class WebUtil
Shared Sub Main(ByVal args As String())
If args.Length <> 2 Then
Return
End If
Dim url As String = args(0)
Dim fileName As String = args(1)
Dim startPos As Long = 0
' ファイルがすでに存在する場合、
' ファイルのサイズを取得する
If File.Exists(fileName) Then
Dim info As New FileInfo(fileName)
startPos = info.Length
End If
WebRequest.DefaultWebProxy = Nothing ' プロキシを使用しない
ResumeDownload(url, fileName, startPos)
End Sub
Public Shared Function ResumeDownload(ByVal url As String, ByVal file As String, ByVal startPos As Long) As Boolean
Console.WriteLine("開始位置:" & startPos)
' リクエストの作成
Dim req As HttpWebRequest _
= CType(WebRequest.Create(url), HttpWebRequest)
' ダウンロード開始位置を設定
req.AddRange(CType(startPos, Integer)
' レスポンスの取得
Dim res As HttpWebResponse _
= CType(req.GetResponse(), HttpWebResponse)
If res.StatusCode <> HttpStatusCode.PartialContent
' レジュームに対応してない場合
res.Close()
return False
End If
Using fs As New FileStream(file, FileMode.OpenOrCreate)
fs.Seek(0, SeekOrigin.End) ' 末尾に追記
Using st As Stream = res.GetResponseStream()
Dim buf(1024) As Byte
Dim count As Integer = 0
Do
count = st.Read(buf, 0, buf.Length)
fs.Write(buf, 0, count)
Loop While count <> 0
End Using
End Using
res.Close()
Return True
End Function
End Class
' コンパイル方法:vbc resumedown.vb
' 実行方法:resumedown.exe <URL> <保存先のファイル名>
|
|
ダウンロードのレジュームを行うVBのサンプル・プログラム(resumedown.vb) |
|
ただし、すべてのWebサーバがダウンロードのレジュームに対応しているわけではないので、そのチェックが必要になる。リクエストでダウンロード範囲の指定を行い、Webサーバがレジュームに対応している場合には、Webサーバからのレスポンスのステータス・コードは「206」になる(はずである)。
この「206」はHttpStatusCode列挙体(System.NET名前空間)のPartialContentとして定義されているので、上記のプログラムでは、この値でレスポンスのステータス・コード(HttpWebResponseオブジェクトのStatusCodeプロパティにより取得可能)をチェックし、Webサーバがレジュームに対応していなければダウンロードを行わないようにしている。
ちなみに、HttpWebRequestクラスのAddRangeメソッドではダウンロード開始位置だけでなく、開始位置と終了位置を指定することもできる。これを利用すれば、1つのファイルを分割して各部分を同時にダウンロードする、いわゆる「分割ダウンロード」も実装できる。
カテゴリ:クラス・ライブラリ 処理対象:ネットワーク
使用ライブラリ:HttpWebRequestクラス(System.Net名前空間)
使用ライブラリ:HttpWebResponseクラス(System.Net名前空間)
使用ライブラリ:HttpStatusCodeクラス(System.Net名前空間)
関連TIPS:WebRequest/WebResponseクラスでWebページを取得するには? |
|
generated by
|
|
Insider.NET 記事ランキング
本日
月間