基於HTTP的單執行緒檔案下載功能實現
阿新 • • 發佈:2019-02-02
思路
- 使用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);
}
}