记录一下使用java的URLConnection类和File类下载网络文件和支持断网断点续传的简单方式
java URLConnection类的结构
demo代码假设下载python的安装包
https://www.python.org/ftp/python/3.10.8/python-3.10.8-amd64.exe
FileDownloadUtilsDemo1.java
package boot.example.file.download;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
/**
* 蚂蚁舞
*/
public class FileDownloadUtilsDemo1 {
// 下载保存的目录 windows系统
public static String localFileName = "D:/MywFileDownLoad/";
public static void main(String[] args) throws IOException {
String urlStr = "https://www.python.org/ftp/python/3.10.8/python-3.10.8-amd64.exe";
downloadFileResourceContinuation(urlStr);
}
public static void downloadFileResourceContinuation(String urlStr){
try {
// 确认本地文件夹是否存在 如果文件夹不存在 自动创建文件夹 创建失败抛出异常
File fileFolder = new File(localFileName);
if (!fileFolder.exists() && !fileFolder.isDirectory()) {
boolean b = fileFolder.mkdirs();
if(!b) {
throw new Exception("创建目录失败");
}
}
// 验证或获取文件的长度
long start = 0; // 默认给0
long end = getFileResourceLength(urlStr); // 远端获取长度
System.out.println("文件长度:"+end);
// 创建网络资源并且获取到连接对象
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 从url对象中获取获得文件名 默认最后一个/后面的就是需要下载的文件资源 这种方式一般不会有问题 当然也可以把目录和文件资源名分开
String file = url.getFile();
String name = file.substring(file.lastIndexOf('/') + 1);
// 去本地文件夹获取该文件 如果存在该文件则判断该文件是否需要再次下载或断点续传
File localFile = new File(localFileName+name);
if(localFile.exists()){
start = localFile.length();
if(start == end){ // 如果相等 那么默认就是下载完成了的
System.out.println("已经下载完成了,无需再次下载");
return;
}
}
// 定义请求范围长度 开始到结束 如果start不是0 那就是断点续传的
String range = "bytes=" + start + "-";
if (end > 0) {
range = range+end;
}
System.out.println(range);
connection.setRequestProperty("RANGE", range);
connection.setRequestProperty("User-Agent", "NetFox");
connection.setRequestMethod("GET");
connection.setReadTimeout(60*1000);
connection.setConnectTimeout(60*1000);
connection.connect();// 连接网络资源
// 要下载文件 这里得到的返回code是206 如果不是206 那么就直接抛出异常失败处理
// System.out.println(connection.getResponseCode()+"--"+connection.getResponseMessage());
if(206 != connection.getResponseCode()){
throw new Exception("获取文件失败!");
}
// 拿到连接后的输入流对象 以及创建本地保存下载资源的输出流对象
InputStream in = connection.getInputStream();
FileOutputStream out = new FileOutputStream(localFileName+name, true);
byte[] buff = new byte[2048];
int len = in.read(buff);
while (len != -1) {
out.write(buff, 0, len);
len = in.read(buff);
}
out.close();
in.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取待下载文件的长度
public static long getFileResourceLength(String urlResource) throws IOException {
URL url=new URL(urlResource);
URLConnection urlConnection=url.openConnection();
urlConnection.connect();
return urlConnection.getContentLength();
}
}
启动main后可以看到控制台
在这里我们把java启动的main关停,相当于网络断了,可以看到下载的文件夹里的python不完整,那么重新启动main
可以看到demo程序是根据之前的断点直接续传的 等待继续下载
等待程序下载结束之后可以再次运行demo的main
可以看到下载确实完成了
运行之后,下载的python没问题
python的网络在国外,下载可能很慢 测试可以使用国内的