แพ็คเกจ cn.me.test;
นำเข้า java.io.InputStream;
นำเข้า java.io.RandomAccessFile;
นำเข้า java.net.HttpURLConnection;
นำเข้า java.net.URL;
-
* ดาวน์โหลดแบบมัลติเธรด
*1: ใช้ RandomAccessFile เพื่อเขียนข้อมูลในทุกตำแหน่ง
*2: จำนวนข้อมูลที่ดาวน์โหลดจากเธรดแรกจำเป็นต้องคำนวณและสามารถกระจายอย่างเท่าเทียมกัน หากไม่เป็นกลางพอ
* จากนั้นเธรดสุดท้ายจะประมวลผลข้อมูลที่มีขนาดค่อนข้างเล็กโดยตรง
*3: ต้องเตรียมไฟล์ที่มีขนาดเท่ากันก่อนดาวน์โหลดและรับผ่านส่วนหัวของไฟล์
-
MultiThreadDownload คลาสสาธารณะ {
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น {
//1: ประกาศชื่อไฟล์และที่อยู่ดาวน์โหลด
ชื่อไฟล์สตริง = "aa.rar";
สตริง urlStr = "http://localhost:7777/day18";
//2: ประกาศ URL
URL url = URL ใหม่ (urlStr+"/"+ชื่อไฟล์);
//3: รับการเชื่อมต่อ
HttpURLConnection แย้ง =
(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);//กำหนดขนาดไฟล์
ไฟล์.ปิด();
//8: กำหนดจำนวนเธรด
ขนาด int = 3;
//9: คำนวณจำนวนไบต์ของข้อมูลแต่ละเธรดที่ควรดาวน์โหลด หากหารลงตัวพอดี จะดีที่สุด ถ้าไม่ใช่ให้บวก 1
int block = length/size==0?length/size:length/size+1;//คำนวณจำนวนข้อมูลที่แต่ละเธรดควรดาวน์โหลด
System.err.println("แต่ละเธรดควรดาวน์โหลด: "+บล็อก);
//10: เรียกใช้สามเธรดและคำนวณว่าไบต์ใดเริ่มต้นและสิ้นสุด
สำหรับ(int i=0;i<ขนาด;i++){
int start = i*block;
int end = start+(block-1);//คำนวณไบต์เริ่มต้นและสิ้นสุดของแต่ละเธรด
System.err.println(i+"="+เริ่มต้น+", "+สิ้นสุด);
ใหม่ MyDownThread(ชื่อไฟล์, เริ่มต้น, สิ้นสุด, url). เริ่มต้น ();
-
-
คลาสคงที่ MyDownThread ขยายเธรด {
//กำหนดชื่อไฟล์
ชื่อไฟล์สตริงส่วนตัว;
//กำหนดตำแหน่งที่จะเริ่มดาวน์โหลด
การเริ่มต้น int ส่วนตัว
//กำหนดไบต์ที่จะดาวน์โหลด
สิ้นสุดส่วนตัว;
URL URL ส่วนตัว;
MyDownThread สาธารณะ (ชื่อไฟล์สตริง, int start, int end, URL url) {
this.fileName=ชื่อไฟล์;
นี้.เริ่มต้น=เริ่มต้น;
นี้.end=สิ้นสุด;
นี้.url=url;
-
@แทนที่
โมฆะสาธารณะวิ่ง () {
พยายาม{
//11: เริ่มดาวน์โหลด
HttpURLConnection แย้ง =
(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//12: ตั้งค่าส่วนหัวคำขอสำหรับการดาวน์โหลดแบบแบ่งส่วน
con.setRequestProperty("Range","bytes="+start+"-"+end);//ตั้งค่าบล็อกไฟล์ที่อ่านจากเซิร์ฟเวอร์
//13: เริ่มดาวน์โหลด ต้องตัดสิน 206
if(con.getResponseCode()==206){//การเข้าถึงสำเร็จ รหัสสถานะที่ส่งคืนคือ 206
InputStream ใน = con.getInputStream();
//14: ประกาศวัตถุไฟล์การเขียนแบบสุ่ม โปรดทราบว่า rwd หมายถึงการเขียนข้อมูลไปยังไฟล์ทันทีโดยไม่ต้องใช้พื้นที่แคช
RandomAccessFile ออก = ใหม่ RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);//ตั้งค่าให้เริ่มเขียนข้อมูลจากตำแหน่งที่แน่นอนในไฟล์
ไบต์ [] b = ไบต์ใหม่ [1024];
อินท์เลน = 0;
ในขณะที่ ((len=in.read(b))!=-1){
out.write(b,0,เลน);
-
ออก.ปิด();
ใน.ปิด();
-
System.err.println(this.getName()+"ดำเนินการเสร็จสิ้น");
} จับ (ข้อยกเว้นจ) {
โยน RuntimeException ใหม่ (e);
-
-
-
-