java 文件断点续下载源码及实例 支持Etag HTTP认证用户名密码

Java (52) 2023-10-05 10:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说java 文件断点续下载源码及实例 支持Etag HTTP认证用户名密码,希望能够帮助你!!!。

以下为java下载网络文件的实例,可支持断点继续下载:

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;
		Long size = -2L;
		try{
			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(url);
			Header header;
			CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpget);
			int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
			if (statusCode > 400) {
				return size;
			}
			header = closeableHttpResponse.getFirstHeader("Content-Length");
			if (header != null) {
				if (null != header.getValue()) {
					size = Long.parseLong(header.getValue());
				}
			}
			closeableHttpResponse.close();
			httpClient.close();
		}catch (Exception e){
			e.printStackTrace();
		}
		return size;
	}

	public static String getFileEtag(String url, String authorUserName, String authorPassword) {
		CloseableHttpClient httpClient;
		String eTag = "";
		try{
			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(url);
			Header header;
			CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpget);
			int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
			if (statusCode > 400) {
				return eTag;
			}
			header = closeableHttpResponse.getFirstHeader("Etag");
			if (header != null) {
				if (null != header.getValue()) {
					eTag = header.getValue().replace("\"","");
				}
			}else{
				header = closeableHttpResponse.getFirstHeader("ETag");
				if (null != header.getValue()) {
					eTag = header.getValue().replace("\"","");
				}
			}
			closeableHttpResponse.close();
			httpClient.close();
		}catch (Exception e){
			e.printStackTrace();
		}
		return eTag;
	}

	public static boolean checkRange(String fileUrl, String authorUserName, String authorPassword) throws IOException {
		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(fileUrl);
		httpget.addHeader("Range", "bytes=0-");
		CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpget);
		Header header = closeableHttpResponse.getFirstHeader("Content-Range");
		if (header != null && header.getValue().length() > "bytes ".length()) {
			closeableHttpResponse.close();
			httpClient.close();
			return true;
		}
		closeableHttpResponse.close();
		httpClient.close();
		return false;
	}

	public static String readFileContent(String path) throws IOException {
		FileInputStream fis = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		try {
			fis = new FileInputStream(path);
			isr = new InputStreamReader(fis, "UTF-8");
			br = new BufferedReader(isr);
			return br.readLine();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(br != null){
				br.close();
			}
			if(isr != null){
				isr.close();
			}
			if(fis != null){
				fis.close();
			}
		}
		return null;
	}

	public static Boolean writeFileContent(String path, String content)  {
		Boolean result = true;
		FileOutputStream fos = null;
		OutputStreamWriter osw = null;
		try {
			fos = new FileOutputStream(path);
			osw = new OutputStreamWriter(fos, "UTF-8");
			osw.write(content);
			osw.flush();
		} catch (FileNotFoundException e) {
			result= false;
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			result= false;
			e.printStackTrace();
		} catch (IOException e) {
			result= false;
			e.printStackTrace();
		} finally {
			try {
				if(osw != null){
					osw.close();
				}
				if(fos != null){
					fos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

   public static void main(String[] args){
      String fileUrl = "http://xxxxxxxx.zip";
      String localPath = "D:\\file\\xxxxxx.zip";
      String tempLocalPath = "D:\\file\\temp\\xxxxxx.zip";
      String authorUserName = null;
      String authorPassword = null;
      boolean isReload = false;
      try {
         downloadFile(fileUrl,localPath, tempLocalPath, authorUserName, authorPassword, isReload);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

}

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

发表回复