الحزمة cn.me.test;
استيراد java.io.InputStream؛
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
استيراد java.net.URL؛
/**
* تنزيل متعدد الخيوط
*1: استخدم RandomAccessFile لكتابة البيانات في أي مكان.
*2: يجب حساب كمية البيانات التي تم تنزيلها بواسطة سلسلة المحادثات الأولى ويمكن توزيعها بالتساوي. إذا لم يكن متوسط بما فيه الكفاية،
* ثم يقوم الخيط الأخير بمعالجة البيانات الصغيرة نسبيًا مباشرةً
*3: يجب تحضير الملفات ذات الحجم نفسه قبل التنزيل والحصول عليها من خلال رأس الملف
*/
الطبقة العامة MultiThreadDownload {
public static void main(String[] args) يطرح الاستثناء {
//1: قم بتعريف اسم الملف وعنوان التنزيل
اسم الملف السلسلة = "aa.rar"؛
String urlStr = "http://localhost:7777/day18";
//2: قم بتعريف عنوان URL
URL url = new URL(urlStr+"/"+fileName);
//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);// اضبط حجم الملف.
file. Close();
//8: تحديد عدد المواضيع
حجم صحيح = 3؛
//9: احسب عدد بايتات البيانات التي يجب على كل موضوع تنزيلها، إذا كانت قابلة للقسمة تمامًا، فمن الأفضل، وإلا أضف 1
int block = length/size==0?length/size:length/size+1;// احسب كمية البيانات التي يجب تنزيلها لكل موضوع.
System.err.println("يجب تنزيل كل موضوع:"+block);
//10: قم بتشغيل ثلاثة سلاسل وحساب البايت الذي يبدأ وينتهي
ل(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 تمتد الموضوع {
// تحديد اسم الملف
اسم ملف سلسلة خاص؛
// تحديد مكان بدء التنزيل
بداية خاصة؛
// تحديد البايت الذي سيتم تنزيله إليه
نهاية كثافة العمليات الخاصة؛
عنوان URL الخاص؛
MyDownThread العامة(String fileName,int start,int end,URL url){
this.fileName=fileName;
this.start=start;
this.end=end;
this.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 in = con.getInputStream();
//14: قم بتعريف كائن ملف الكتابة العشوائي، لاحظ أن rwd يشير إلى كتابة البيانات إلى الملف على الفور دون استخدام منطقة ذاكرة التخزين المؤقت.
RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);// اضبط لبدء كتابة البيانات من موضع معين في الملف.
بايت[] ب=بايت جديد[1024];
إنت لين = 0;
بينما((لين=in.read(ب))!=-1){
out.write(b,0,len);
}
out.Close();
in. Close();
}
System.err.println(this.getName()+"اكتمال التنفيذ");
}قبض(استثناء ه){
رمي RuntimeException (e) الجديد ؛
}
}
}
}