пакет 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) выдает исключение {
//1: объявить имя файла и адрес загрузки
Строка fileName = "aa.rar";
Строка urlStr = "http://localhost:7777/day18";
//2: Объявить URL
URL-адрес URL = новый URL-адрес(urlStr+"/"+имя_файла);
//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);//Установим размер файла.
файл.закрыть();
//8: Определить количество потоков
размер int = 3;
//9: Вычисляем, сколько байт данных должен загрузить каждый поток. Лучше всего, если оно делится ровно, в противном случае добавьте 1.
int block = length/size==0?length/size:length/size+1;//Рассчитываем объем данных, который должен загрузить каждый поток.
System.err.println("Каждый поток должен загрузить: "+block);
//10: Запускаем три потока и вычисляем, какой байт начинается и заканчивается
for(int i=0;i<size;i++){
int start = я*блок;
int end = start+(block-1);//Вычисляем начальный и конечный байты каждого потока.
System.err.println(i+"="+start+","+end);
новый MyDownThread (имя_файла, начало, конец, URL).start();
}
}
статический класс MyDownThread расширяет Thread {
//Определяем имя файла
частная строка имя_файла;
//Определяем, с чего начать загрузку
частный запуск int;
//Определяем, в какой байт загрузить
частный int конец;
частный URL-адрес;
public MyDownThread (String fileName, int start, int end, URL-адрес) {
this.fileName=имя_файла;
this.start=начало;
this.end=конец;
this.url=url;
}
@Override
общественный недействительный запуск () {
пытаться{
//11: Начать загрузку
HttpURLConnection con=
(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 = новый RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);//Устанавливаем начало записи данных с определенной позиции в файле.
байт[] b=новый байт[1024];
интервал лен = 0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
выход.закрыть();
в.закрыть();
}
System.err.println(this.getName()+"Выполнение завершено");
}catch(Исключение е){
выдать новое RuntimeException(e);
}
}
}
}