/**
* Alipay.com Inc.
* Copyright (c) 2005-2009 All Rights Reserved.
*/
package com.external.alipay;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
/**
*
* @author jianmin.jiang
*
* @version $Id: FileFetch.java, v 0.1 2012-2-14 下午8:55:40 jianmin.jiang Exp $
*/
final class FileFetch implements Runnable {
private String fileUrl;
private String savePath;
private FileDownloader downloader;
private boolean stop = false;
private long fileStart;
private long fileEnd;
public FileFetch(String fileUrl, String savePath, FileDownloader downloader) {
this.fileUrl = fileUrl;
this.savePath = savePath;
this.downloader = downloader;
}
public void run() {
if (downloader.showProgress()) {
if (fileEnd <= 0 || fileStart >= fileEnd) {
this.stop = true;
return;
}
}
boolean canStop = false;
FileAccess fileAccess = new FileAccess();
while (!this.stop) {
InputStream input = null;
int responseCode = 0;
try {
try {
HttpGet httpGet = new HttpGet(fileUrl);
// 取得HttpClient
HttpClient httpClient = new DefaultHttpClient();
if (downloader.showProgress()) {
String property = "bytes=" + fileStart + "-" + fileEnd;
// conn.setRequestProperty("RANGE", property);
httpGet.addHeader("Range", property);
}
// 请求HttpClient,获得HttpResponce
HttpResponse response = httpClient.execute(httpGet);
// 请求成功
responseCode = response.getStatusLine().getStatusCode();
switch (responseCode) {
case HttpStatus.SC_OK:
case HttpStatus.SC_CREATED:
case HttpStatus.SC_ACCEPTED:
case HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION:
case HttpStatus.SC_NO_CONTENT:
case HttpStatus.SC_RESET_CONTENT:
case HttpStatus.SC_PARTIAL_CONTENT:
case HttpStatus.SC_MULTI_STATUS:
input = response.getEntity().getContent();
break;
default:
this.stop = true;
break;
}
if (this.stop) {
break;// 返回失败结果,不需要再下载文件
}
} catch (IOException e) {
e.printStackTrace();
}
if (input == null) {
continue;
}
int size;
byte[] buffer = new byte[1024];
do {
size = input.read(buffer, 0, buffer.length);
if (size != -1) {
this.fileStart += fileAccess.write(buffer, 0, size);
this.downloader.writeTempFile();
}
canStop = downloader.showProgress() ? fileStart < fileEnd
: true;
canStop = !stop && canStop;
} while (size > -1 && canStop);
this.stop = true;
} catch (SocketTimeoutException e) {
if (responseCode == 0) {
this.stop = true;
}
} catch (IOException e) {
this.stop = true;
} catch (Exception e) {
this.stop = true;
} finally {
if (input != null)
try {
input.close();
} catch (Exception e) {
}
}
}
fileAccess.close();
}
public final long getFileStart() {
return fileStart;
}
public final void setFileStart(long fileStart) {
this.fileStart = fileStart;
}
public final long getFileEnd() {
return fileEnd;
}
public final void setFileEnd(long fileEnd) {
this.fileEnd = fileEnd;
}
public final boolean isStop() {
return this.stop;
}
public final void stop() {
stop = true;
}
final class FileAccess {
private FileOutputStream outStream;
public FileAccess() {
try {
/**
* 只能保存在程序的files目录下。如果放在files的子文件夹下,会出现读取权限的问题
* 第二个参数设置为true,表示可以追加数据,实现断点续传。
*
* 在此处写入的文件是不可读的,会在下载完成后改成可读。
*/
outStream = new FileOutputStream(savePath, true);
} catch (FileNotFoundException e) {
// 在以上bean.createFile()中已创建文件,不会产生这个例外
e.printStackTrace();
}
}
public synchronized int write(byte[] b, int start, int len)
throws IOException {
outStream.write(b, start, len);
return len;
}
public void close() {
try {
outStream.close();
} catch (Exception e) {
}
}
}
}