思路
- 使用http请求远程文件地址
- 从响应体中获取文件头信息
- 读取响应体中的输入流,并写入本地文件输出流中
代码实现
package org.hanmeis;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
/**
* Created by zhao.wu on 2016/12/7.
* 单线程下载
* 使用方法:SingleDownloader [url]
*/
public class SingleDownloader {
private static Logger logger = Logger.getLogger("SingleDownloader");
public static void main(String[] args) throws IOException {
String url;
if(args.length<1){
System.out.print("输入下载地址:");
url = new Scanner(System.in).nextLine();
}else {
url = args[0];
}
SingleDownloader singleDownloader = new SingleDownloader(url);
singleDownloader.connectServer();
singleDownloader.startDownload();
}
private URL url;
private String fileName;
private long fileSize;
private long preSize;
private long currentSize;
private InputStream is;
private OutputStream os;
private Timer timer = new Timer();
private SingleDownloader(){
logger.info("新任务加入下载队列......");
}
private SingleDownloader(String url) throws MalformedURLException {
this();
this.url = new URL(url);
}
/**
* 连接远程服务器,并获取文件信息:大小,文件名
* @throws IOException
*/
private void connectServer() throws IOException {
logger.info(String.format("连接服务器:%s://%s",url.getProtocol(),url.getHost()));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10*1000);
this.fileSize = Long.parseLong(connection.getHeaderField("Content-Length"));
String[] temp = url.getFile().split("/");
if(temp.length!=0) {
this.fileName = temp[temp.length - 1];
}
this.is = connection.getInputStream();
this.os = new FileOutputStream(this.fileName);
logger.info(String.format("文件名:%s 大小:%.2fM", this.fileName, this.fileSize*1.0/1024/1024));
}
/**
* 下载过程
* @throws IOException
*/
private void startDownload() throws IOException {
logger.info(String.format("开始下载:%s",fileName));
info();
byte[] bs = new byte[5120];
int len;
while((len = is.read(bs))>0){
os.write(bs);
this.currentSize += len;
}
is.close();
os.close();
timer.cancel();
logger.info(String.format("完成下载:%s",fileName));
}
/**
* 定时计算下载状态
*/
private void info(){
timer.schedule(new TimerTask() {
@Override
public void run() {
long tempC = currentSize;
long tempSize = tempC-preSize;
preSize = tempC;
double percent = (tempC*100.0)/fileSize;
double speed = (tempSize*1.0)/1024/3;
logger.info(String.format("文件:%s 已完成:%.2f%% 速率:%.2fkb/s",fileName, percent, speed));
}
},0, 3000);
}
}