目标:快速上传下载x度网盘文件 (实测一点不快,3.7M文件上传8秒左右,下载40秒左右)
环境:JDK1.8x64
前提:开通API,创建app, 获取token.
package baidupan.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.time.Duration;
import java.time.Instant;
public class BaiduPan_up_down {
// https://pan.baidu.com/union/doc/
// 开通百度网盘API,创建应用app1,获取ACCESS_TOKEN (简化模式,有效期30天)
private static final String ACCESS_TOKEN = "123.456xxxx.789xxxx.Vq-M_w";
private static final String SAVE_PATH = "/apps/app1/"; //apps 这个名字不要修改,通过网盘查看的名字是"我的应用数据",app1 是创建应用的名字。
public static String formatJson(String json) {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Object obj = null;
try {
obj = mapper.readValue(json, Object.class);
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static String upload(String filePath){
Instant start = Instant.now();
String fs_id = "";
//TODO:qjp 必须https !!!
String UPLOAD_URL = "https://d.pcs.baidu.com/rest/2.0/pcs/file?method=upload&ondup=overwrite&access_token=" +ACCESS_TOKEN+"&path="+ SAVE_PATH + filePath ;
File file = new File(filePath);
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(UPLOAD_URL);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", file);
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
try {
HttpResponse response = httpClient.execute(httpPost);
String jsonStr = EntityUtils.toString(response.getEntity());
//System.out.println("response = " + formatJson(jsonStr));
JSONObject jsonObj = null;
jsonObj = new JSONObject(jsonStr);
if (jsonObj.has("error_code")) {
System.out.println("Upload failed: " + jsonObj.getString("error_msg"));
} else {
fs_id = jsonObj.getString("fs_id");
System.out.println("Upload success: " + jsonObj.getString("path") + ", fs_id = " + fs_id);
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JSONException e) {
throw new RuntimeException(e);
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("upload 方法执行时间:" + duration.toMillis() + "毫秒");
return fs_id;
}
public static String get_file_info(String fs_id) {
Instant start = Instant.now();
String dlink = "";
try {
URL url = new URL("https://pan.baidu.com/rest/2.0/xpan/multimedia?method=filemetas&access_token="+ACCESS_TOKEN+"&fsids=%5B"+fs_id +"%5D&thumb=1&dlink=1&extra=1&needmedia=1&detail=1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//System.out.println(formatJson(response.toString()));
//dlink有效期为8小时
//dlink存在302跳转
//不允许使用浏览器直接下载超过50MB的文件
JSONObject jsonObj = new JSONObject(response.toString());
JSONArray list = jsonObj.getJSONArray("list");
Object obj_list1 = list.get(0);
JSONObject json_list1 = new JSONObject(obj_list1.toString());
if (json_list1.has("dlink")) {
dlink = json_list1.getString("dlink");
System.out.println("fs_id = " +fs_id + ", + dlink = " + dlink);
} else {
System.out.println("get_file_info error");
}
} catch (Exception e) {
System.out.println(e);
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("get_file_info 方法执行时间:" + duration.toMillis() + "毫秒");
return dlink;
}
public static void download(String dlink,String savepath) {
Instant start = Instant.now();
DecimalFormat df = new DecimalFormat("#.#");
dlink = dlink + "&access_token=" + ACCESS_TOKEN;
try {
URL url = new URL(dlink);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("User-Agent", "pan.baidu.com");
httpConn.setRequestProperty("Host", "d.pcs.baidu.com");
httpConn.setInstanceFollowRedirects(true);
int responseCode = httpConn.getResponseCode();
//System.out.println("responseCode = " + responseCode);
if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM) {
// 处理 302 跳转
String newUrl = httpConn.getHeaderField("Location");
System.out.println("Location = " + newUrl);
//String disposition = httpConn.getHeaderField("Content-Disposition");
//System.out.println("disposition = " + disposition);
httpConn = (HttpURLConnection) new URL(newUrl).openConnection();
httpConn.connect();
}
// 创建文件
File file = new File(savepath);
FileOutputStream fos = new FileOutputStream(file);
// 读取数据并写入文件
int downloadedSize = 0;
long startTime = System.currentTimeMillis();
long endTime = 0L;
double speed = 0L;
double progress = 0L;
double result = 0L;
int fileSize = httpConn.getContentLength();
String file_size = formatFileSize(fileSize);
System.out.println("\r\n开始下载:size = " + file_size);
InputStream is = httpConn.getInputStream();
byte[] buffer = new byte[1048576];
int bytesRead = -1;
while ((bytesRead = is.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
downloadedSize += bytesRead;
endTime = System.currentTimeMillis();
if(downloadedSize % 1024 == 0 || downloadedSize == fileSize){
speed = downloadedSize / (endTime - startTime) * 1000;
String speedStr = formatFileSize(speed) + "/s";
progress = (double) downloadedSize / fileSize * 100;
result = Double.parseDouble(df.format(progress));
System.out.print("\r下载速度:" + speedStr + ",下载进度 ( " +formatFileSize(downloadedSize) + " / "+ file_size+"):" + result + "%");
}
}
// 关闭连接和流
fos.close();
is.close();
httpConn.disconnect();
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("\r\ndownload 方法执行时间:" + duration.toMillis() + "毫秒");
System.out.println("文件下载完成 = " + savepath);
} catch (Exception e) {
System.out.println(e);
}
}
public static String formatFileSize(double fileSize) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString = "";
if (fileSize < 1024) {
fileSizeString = df.format(fileSize) + " B";
} else if (fileSize < 1048576) {
fileSizeString = df.format(fileSize / 1024) + " KB";
} else if (fileSize < 1073741824) {
fileSizeString = df.format(fileSize / 1048576) + " MB";
} else {
fileSizeString = df.format(fileSize / 1073741824) + " GB";
}
return fileSizeString;
}
public static void main(String[] args) throws IOException {
//String filePath = "pass.jpg";
//String filePath = "upload/test.pdf"; //上传文件大小上限为2GB
String filePath = "upload/3.7M.pdf";
// filePath = "upload/qemumanager.rar";
String savepath = "download/3.7M.pdf";
String fs_id = upload(filePath);
String dlink = get_file_info(fs_id);
download(dlink,savepath);
}
}