package com.leizhu;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
/**
* Created by 01312170 on 14-12-24.
*/
public class HttpClientUtils {
private static int BUF = 4096;
private static int FILE_BUF = 1024 * 1024;
/**
* 下载
* @param fileUrl 文件HTTP地址
* @param localPath 文件本地路径
* @param tempLocalPath 文件本地临时路径
* @param isReload 是否需要重新下载
* @param authorUserName 认证用户名
* @param authorUserName 认证密码
* @return
* @throws IOException
* @throws URISyntaxException
*/
public static boolean downloadFile(String fileUrl, String localPath,
String tempLocalPath, String authorUserName, String authorPassword, boolean isReload) throws Exception {
Map<String, Long> params = new HashMap<String, Long>();
boolean result = true;
// 获取服务器上文件大小
long fileSize = getFileSize(fileUrl , authorUserName, authorPassword);
params.put("fileSize", fileSize);
params.put("currentSize", 0L);
// 实际大小小于等于0,无需下载
if (fileSize <= 0) {
//return params;
return false;
}
// 本地大小与实际大小不同,需要重新下载
long localSize = 0;
File file = new File(localPath);
if (!(file.getParentFile().exists() && file.getParentFile().isDirectory())) {
file.getParentFile().mkdirs();
}
File tempFile = new File(tempLocalPath);
if (!(tempFile.getParentFile().exists() && tempFile.getParentFile().isDirectory())) {
tempFile.getParentFile().mkdirs();
}
String fileEtag = getFileEtag(fileUrl , authorUserName, authorPassword);
String etagFilePath = "";
if(fileEtag != null){
etagFilePath = tempFile.getParentFile().getPath().concat(File.separator).concat(tempFile.getName()).concat("_etag.txt");
if(new File(etagFilePath).exists()){
String oldFileEtag = readFileContent(etagFilePath);
if(oldFileEtag == null){
System.out.println("==========读取文件失败============");
return false;
}
if(!fileEtag.equals(oldFileEtag)){
isReload = true;
//写入新的etag
if(!writeFileContent(etagFilePath, fileEtag)){
System.out.println("==========写入文件失败============");
return false;
};
}else{
//临时目录不存在,目标目录存在,且目标目录文件大小和线上大小相同则不需要下载,直接返回下载成功
if(!tempFile.exists() && file.exists() && file.length() == fileSize){
return true;
}
}
}else{
if(!writeFileContent(etagFilePath, fileEtag)){
System.out.println("==========写入文件失败============");
return false;
};
}
}
// 检测是否支持断点下载
if (checkRange(fileUrl, authorUserName, authorPassword)) {
if(tempFile.exists()){
if(tempFile.length() == fileSize){
moveFile(tempFile.getAbsolutePath(), file.getAbsolutePath());
return true;
}
}
//支持分段
RandomAccessFile tempLocalFile = new RandomAccessFile(tempLocalPath, "rw");
localSize = tempLocalFile.length();
if (localSize > fileSize || isReload) {
localSize = 0;
tempLocalFile.setLength(0);
}
CloseableHttpResponse response = null;
try {
URIBuilder uriBuilder = new URIBuilder(fileUrl);
CloseableHttpClient httpClient;
if(null != authorUserName && null != authorPassword){
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(authorUserName, authorPassword);
provider.setCredentials(AuthScope.ANY, credentials);
httpClient = HttpClients.custom().setDefaultCredentialsProvider(provider).build();
}else{
httpClient = HttpClients.createDefault();
}
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("Range", "bytes=" + localSize + "-");
response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
byte[] _r = new byte[FILE_BUF];
int length;
while ((length = instream.read(_r)) != -1) {
tempLocalFile.seek(localSize);
tempLocalFile.write(_r, 0, length);
localSize = localSize + length;
}
} catch (Exception e) {
result = false;
e.printStackTrace();
throw new Exception();
} finally {
instream.close();
}
}
}catch (Exception e){
result = false;
e.printStackTrace();
throw new Exception();
}finally {
if(response != null){
response.close();
}
if(tempLocalFile != null){
tempLocalFile.close();
}
}
} else {
//不支持分段
RandomAccessFile tempLocalFile = new RandomAccessFile(tempLocalPath, "rw");
localSize = 0;
CloseableHttpResponse response = null;
try {
URIBuilder uriBuilder = new URIBuilder(fileUrl);
CloseableHttpClient httpClient;
if(null != authorUserName && null != authorPassword){
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(authorUserName, authorPassword);
provider.setCredentials(AuthScope.ANY, credentials);
httpClient = HttpClients.custom().setDefaultCredentialsProvider(provider).build();
}else{
httpClient = HttpClients.createDefault();
}
HttpGet httpGet = new HttpGet(uriBuilder.build());
response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
byte[] _r = new byte[FILE_BUF];
int length;
while ((length = instream.read(_r)) != -1) {
tempLocalFile.seek(localSize);
tempLocalFile.write(_r, 0, length);
localSize = localSize + length;
}
} catch (Exception e) {
result = false;
e.printStackTrace();
throw new Exception();
} finally {
if(instream != null){
instream.close();
}
}
}
} catch (Exception e){
e.printStackTrace();
result = false;
throw new Exception();
} finally {
if(response != null){
response.close();
}
if(tempLocalFile != null){
tempLocalFile.close();
}
}
}
if (localSize == fileSize) {
try{
moveFile(tempLocalPath, localPath);
}catch (Exception e){
result = false;
e.printStackTrace();
}
}else{
result = false;
}
params.put("currentSize", localSize);
//下载完成,并且在linux系统下,更改权限
return result;
}
public static void moveFile(String source, String target) {
try {
Files.move(Paths.get(source), Paths.get(target), StandardCopyOption.REPLACE_EXISTING);
System.out.println("File is moved successful!");
} catch (Exception e) {
System.out.println("File is failed to move!");
e.printStackTrace();
}
}
public static long getFileSize(String url, String authorUserName, String authorPassword) {
CloseableHttpClient httpClient;
Lon