您的位置:首页 > 理论基础 > 计算机网络

Java网络编程之单线程下载文件---多线程下载单个文件

2018-07-30 09:06 501 查看

一,单线程下载文件

下载文件的时候,如果为了用户友好,都会给予进度条提醒用户,那么怎么做呢?
其实很简单,首先获取服务器文件的大小
urlConnection.getContentLength(),然后在读取文件过程计算文件百分比增长即可

 
 
/**
* 文件下载工具 by sam on 2018/7/30.
*/
public final class FileUtil {

/**
* 单线程下载文件
* @param url 文件的网络地址
* @param path 保存的文件地址
*/
public static void dowanload(String url, String path)
throws IOException {
System.out.println("下载中...");
InputStream inputStream = null;
RandomAccessFile randomAccessFile = null;
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(10 * 1000);
File file = new File(path);
if (!file.getParentFile().exists())
file.getParentFile().mkdir();
if (file.exists())
file.delete();
file.createNewFile();
int responseCode = urlConnection.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
inputStream = urlConnection.getInputStream();
int len = 0;
byte[] data = new byte[4096];
int progres = 0; //用于保存当前进度(具体进度)
int maxProgres = urlConnection.getContentLength();//获取文件
randomAccessFile = new RandomAccessFile(file, "rwd");
randomAccessFile.setLength(maxProgres);//设置文件大小
int unit = maxProgres / 100;//将文件大小分成100分,每一分的大小为unit
int unitProgress = 0; //用于保存当前进度(1~100%)
while (-1 != (len = inputStream.read(data))) {
randomAccessFile.write(data, 0, len);
progres += len;//保存当前具体进度
int temp = progres / unit; //计算当前百分比进度
if (temp >= 1 && temp > unitProgress) {//如果下载过程出现百分比变化
unitProgress = temp;//保存当前百分比
System.out.println("正在下载中..." + unitProgress + "%");
}
}
inputStream.close();
System.out.println("下载完成...");
} else {
System.out.println("服务器异常...");
}
} finally {
if (null != inputStream) {
inputStream.close();
}
if (null != randomAccessFile) {
randomAccessFile.close();
}
}
}

public static void main(String[] args) throws IOException {
String path = "";//文件存放路径
String url = "";//获取文件的路径地址
FileUtil.dowanload(url, path);
}
}

文章出处:https://www.geek-share.com/detail/2657704764.html

二,多线程下载单个文件

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

/**
实现思路:将文件分成 n块,每块用不同线程去下载,

* 文件下载工具 by sam on 2018/07/30.
*/
public final class FileUtil {

/**
* 单线程下载文件
*
* @param url       文件的网络地址
* @param path      保存的文件路径
* @param threadNum 想要开启的线程数
*/
public static void dowanload(String url, String path, int threadNum)
throws IOException {
System.out.println("下载中...");
InputStream inputStream = null;
RandomAccessFile randomAccessFile = null;
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(10 * 1000);
File file = new File(path);
if (!file.getParentFile().exists())
file.getParentFile().mkdir();
if (file.exists())
file.delete();
file.createNewFile();
int responseCode = urlConnection.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
int fileSize = urlConnection.getContentLength();//获取文件大小
randomAccessFile = new RandomAccessFile(file, "rwd");
randomAccessFile.setLength(fileSize);//设置文件大小
randomAccessFile.close();//设置文件大小后关闭

//获取线程要处理的块数
int value = fileSize % threadNum;
int unit = fileSize/threadNum;//文件平均每块大小
int block = 0 == value ? threadNum: threadNum + 1; //如果不整除,分多一块处理
for (int i = 0; i < block; i++) {
int startMark = i * unit;//开始下载位置
int endMark = (i + 1) * unit - 1;//下载末端位置
DownloadFileThread thread = new DownloadFileThread(url, file, startMark, endMark);
thread.start();
}

} else {
System.out.println("服务器异常...");
}
} finally {
if (null != inputStream) {
inputStream.close();
}
if (null != randomAccessFile) {
randomAccessFile.close();
}
}
}

/***
* 下载文件块线程
*/
private static class DownloadFileThread extends Thread {
private String url;
private File file;
private int startMark;
private int endMark;

public DownloadFileThread(String url, File file, int startMark, int endMark) {
this.url = url;
this.file = file;
this.startMark = startMark;
this.endMark = endMark;
}

@Override
public void run() {
InputStream inputStream = null;
RandomAccessFile randomAccessFile = null;
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(10 * 1000);
//请求指定文件的位置,表明当前的一块获取的开始下载位置到末端位置
urlConnection.setRequestProperty("Range", "bytes="+startMark+"-"+endMark);
int responseCode = urlConnection.getResponseCode();
if (responseCode >= 200 && responseCode < 300)
{
inputStream = urlConnection.getInputStream();
int len = 0;
byte[] data = new byte[4096];
randomAccessFile = new RandomAccessFile(file, "rwd");
randomAccessFile.seek(startMark);//设置往文件写入部分
while (-1 != (len = inputStream.read(data))) {
randomAccessFile.write(data, 0, len);
}
System.out.println("下载完成..."+getName());
}
else
{
System.out.println("服务器异常...");
}
} catch (Exception ex) {

}
finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != randomAccessFile) {
try {
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}
}

public static void main(String[] args) throws IOException {
String path = "";
String url = "";
FileUtil.dowanload(url, path, 4);
}
}

文章出处:https://www.geek-share.com/detail/2657742080.html

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: