パッケージcn.me.test;
java.io.InputStreamをインポートします。
java.io.RandomAccessFile をインポートします。
java.net.HttpURLConnectionをインポートします。
java.net.URLをインポートします。
/**
*マルチスレッドダウンロード
*1: RandomAccessFile を使用して、任意の場所にデータを書き込みます。
*2: 最初のスレッドによってダウンロードされるデータ量を計算し、均等に分散する必要があります。十分に平均的でない場合は、
* その後、最後のスレッドが比較的小さなデータを直接処理します
※3:ダウンロード前に同じサイズのファイルを用意し、ファイルヘッダーから取得する必要があります。
*/
パブリック クラス MultiThreadDownload {
public static void main(String[] args) throws Exception {
//1: ファイル名とダウンロードアドレスを宣言
文字列ファイル名 = "aa.rar";
文字列 urlStr = "http://localhost:7777/day18";
//2: URLを宣言する
URL url = 新しい URL(urlStr+"/"+fileName);
//3: 接続を取得します
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
//4:リクエストメソッドを設定する
con.setRequestMethod("GET");
//5: ファイルの長さであるリクエストヘッダーを取得します。
int length = con.getContentLength();//ダウンロードされたファイルの長さを取得して、各スレッドがダウンロードする必要があるデータの量を計算します。
//6: 指定したディレクトリに同じサイズのファイルを作成
RandomAccessFile file = new RandomAccessFile("d:/a/"+fileName, "rw");//同じサイズのファイルを作成します。
//7: ファイルサイズ、プレースホルダーを設定
file.setLength(length);//ファイルサイズを設定します。
file.close();
//8: スレッド数を定義する
int サイズ = 3;
//9: 各スレッドがダウンロードするデータのバイト数を計算します。それが正確に割り切れる場合はそれが最適で、そうでない場合は 1 を加算します。
int block = length/size==0?length/size:length/size+1;//各スレッドがダウンロードするデータの量を計算します。
System.err.println("各スレッドはダウンロードする必要があります: "+block);
//10: 3 つのスレッドを実行し、どのバイトが開始して終了するかを計算します
for(int i=0;i<size;i++){
int start = i*block;
int end = start+(block-1);//各スレッドの開始バイトと終了バイトを計算します。
System.err.println(i+"="+start+","+end);
new MyDownThread(fileName, start, end,url).start();
}
}
静的クラス MyDownThread extends Thread{
//ファイル名を定義
プライベート文字列ファイル名;
//ダウンロードを開始する場所を定義します
プライベート int 開始;
//ダウンロード先のバイトを定義
プライベート int エンド;
プライベート URL URL;
public MyDownThread(String fileName,int start,int end,URL url){
this.fileName=ファイル名;
this.start=スタート;
this.end=終わり;
this.url=url;
}
@オーバーライド
public void run() {
試す{
//11: ダウンロード開始
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//12: セグメント化されたダウンロードのリクエスト ヘッダーを設定します
con.setRequestProperty("Range","bytes="+start+"-"+end);//サーバーから読み込むファイルブロックを設定します。
//13: ダウンロードを開始します。206 を判断する必要があります
if(con.getResponseCode()==206){//アクセスが成功した場合、返されるステータス コードは 206 です。
入力ストリーム = con.getInputStream();
//14: ランダム書き込みファイル オブジェクトを宣言します。rwd は、キャッシュ領域を使用せずにデータをただちにファイルに書き込むことを指します。
RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);//ファイル内の特定の位置からデータの書き込みを開始するように設定します。
byte[] b=新しいバイト[1024];
int len = 0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
out.close();
in.close();
}
System.err.println(this.getName()+"実行が完了しました");
}catch(例外 e){
新しい RuntimeException(e) をスローします。
}
}
}
}