JAVA实现百度网盘文件上传

配置信息的获取可以看专栏中的其他博客
一、常量配置
package com.shp.dev.service.baidu;/*** @Description: TODO 百度网盘基本常量信息*/
public interface Constant {String APP_ID="24110959";String APP_NAME="云存储";String APP_KEY="cVQ2xjHGyzsIzq3kxKXK5dEzclBDGrxG";String SECRET_KEY="DaZzd20bxXf9PPNOArPEpICsxc4yMgpf";String SING_key="aA4nWN4oMyRpJ6^N%1K7X0jmeFfUhlkq";String APP_PATH="/apps/"+APP_NAME+"/";//单位mb// 普通用户单个分片大小固定为4MB(文件大小如果小于4MB,无需切片,直接上传即可),单文件总大小上限为4G。//普通会员用户单个分片大小上限为16MB,单文件总大小上限为10G。//超级会员用户单个分片大小上限为32MB,单文件总大小上限为20G。Integer UNIT=32;//获取授权码,需要扫码登陆String GET_CODE_URL="https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id="+APP_KEY+"&redirect_uri=oob&scope=basic,netdisk&display=tv&qrcode=1&force_login=1";//获取到的授权码String CODE="389853bcabdb033c1bcf3e6b5a6dba61";//根据授权码换取tokenString GET_TOKEN_BY_CODE="https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code="+CODE+"&client_id="+APP_KEY+"&client_secret="+SECRET_KEY+"&redirect_uri=oob";//获取到的TOKENString RTOKEN="122.fec5f9d6dd1644c2c57c89cc510f7ec8.YBMpVZwjo9y5kSMFnVmSMJL9dj25T5X02gjLwV8.1J2sEw";String ATOKEN="121.03680b5ab4a5fe8dba360b09f161595e.Yga1poFnDVL6-w3_cDt3xtJtMUKbHuoCaO3CmYO.TxDw4Q";//操作文件 copy, mover, rename, deleteString FILE_MANAGER_URL=" https://pan.baidu.com/rest/2.0/xpan/file";//预上传String GET_READY_FILE_URL="https://pan.baidu.com/rest/2.0/xpan/file";//分片上传String SLICING_UPLOAD_FILE_URL="https://d.pcs.baidu.com/rest/2.0/pcs/superfile2";//下载文件String DOWN_LOUE_URL="https://pan.baidu.com/rest/2.0/xpan/multimedia";//文件搜索String FILE_SEARCH="https://pan.baidu.com/rest/2.0/xpan/file?method=search";}
二、文件上传工具
package com.shp.dev.service.baidu;import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;import static com.shp.dev.service.baidu.Constant.*;/*** @Description: TODO 上传文件到百度网盘*/@Slf4j
public class FileUtils {@SneakyThrowspublic static void main(String[] args) {//不能有空格String filePath = "C:\\Users\\Administrator\\Desktop\\分片\\";String fileName = "a.jpg";System.out.println(save(filePath, fileName));}/*** @Description: TODO 保存文件* @param: filePath 文件路径* @param: fileName 文件名称* return 文件下载地址*/private static String save(String filePath, String fileName) {//本地文件地址String absoluteFilePath = filePath + fileName;//云端文件地址String cloudPath = APP_PATH + fileName;//文件分片并获取md5值File file = new File(absoluteFilePath);File[] separate = separate(absoluteFilePath, UNIT);StringBuffer md5s = new StringBuffer();if (separate.length == 1) {md5s.append(getMD5(separate[0]));}if (separate.length > 1) {for (int i = 0; i < separate.length; i++) {md5s.append(getMD5(separate[i]) + "\",\"");log.info("正在分片,{}{}", separate[i].toString(), i);}String s = md5s.toString();md5s = new StringBuffer(s.substring(0, md5s.length() - 3));}//预上传String precreate = precreate(cloudPath, file.length(), 0, md5s.toString());log.info("预上传{}", precreate);//分片上传String upload = upload(cloudPath, (String) new JSONObject(precreate).get("uploadid"), separate);log.info("分片上传{}", upload);//创建文件String create = create(fileName, file.length(), 0, md5s.toString());log.info("创建文件{}", create);//获取下载地址String downUrl = getDownUrl(fileName);log.info("获取下载地址{}", downUrl);return downUrl;}/*** @Description: TODO 获取下载地址* @param: fileName 文件名*/private static String getDownUrl(String fileName) {String fileSearch = HttpUtil.get(FILE_SEARCH + "&access_token=" + ATOKEN + "&key=" + fileName);JSONObject jsonObject = new JSONObject(fileSearch);JSONArray list = jsonObject.getJSONArray("list");JSONObject listJSONObject = list.getJSONObject(0);Long fs_id = listJSONObject.getLong("fs_id");String url = DOWN_LOUE_URL + "?method=filemetas&access_token=" + ATOKEN + "&fsids=[" + fs_id + "]&dlink=1";String s = HttpUtil.get(url);JSONObject sJsonObject = new JSONObject(s);JSONArray jsonArray = sJsonObject.getJSONArray("list");JSONObject jsonObjectClient = jsonArray.getJSONObject(0);String dlink = jsonObjectClient.getStr("dlink");return dlink;}/*** @Description: TODO 创建文件* @param: fileName 文件名称* @param: size 文件大小 字节* @param: isDir 0文件 1目录(设置为目录是 size要设置为0)* @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传* @return: java.lang.String*/private static String create(String fileName, Long size, Integer isDir, String blockList) {String strURL = FILE_MANAGER_URL + "?method=create&access_token=" + ATOKEN;String params = "path=" + APP_PATH + fileName + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir;return open(strURL, params, "POST");}/*** @Description: TODO 分片上传* @param: path 上传到百度网盘的地址* @param: uploadid 上传的id* @param: filePath 本地文件的地址* @return: java.lang.String*/private static String upload(String path, String uploadid, File[] files) {try {for (int i = 0; i < files.length; i++) {String url = SLICING_UPLOAD_FILE_URL + "?method=upload" +"&access_token=" + ATOKEN +"&type=tmpfile&partseq=" + i +"&path=" + path +"&uploadid=" + uploadid;String s = sendFile(url, files[i]);log.info("正在上传分片文件{}{}", s, i);}return path;} catch (Exception e) {e.printStackTrace();}return null;}/*** @Description: TODO 预上传* @param: cloudPath 云端路径* @param: size 文件大小 字节* @param: isDir 0文件 1目录(设置为目录是 size要设置为0)* @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传* @return: java.lang.String*/private static String precreate(String cloudPath, Long size, Integer isDir, String blockList) {String strURL = GET_READY_FILE_URL + "?method=precreate&access_token=" + ATOKEN;String params = "path=" + cloudPath + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir;return open(strURL, params, "POST");}/*** @Description: TODO 获取md5值* String path 文件地址*/private final static String[] strHex = {"0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};private static String getMD5(File path) {StringBuilder buffer = new StringBuilder();try {MessageDigest md = MessageDigest.getInstance("MD5");byte[] b = md.digest(org.apache.commons.io.FileUtils.readFileToByteArray(path));for (int value : b) {int d = value;if (d < 0) {d += 256;}int d1 = d / 16;int d2 = d % 16;buffer.append(strHex[d1]).append(strHex[d2]);}return buffer.toString();} catch (Exception e) {return null;}}/*** @Description: TODO* @param: strURL 网址,可以是 http://aaa?bbb=1&ccc=2 拼接的* @param: params 拼接的body参数也就是form表单的参数  ddd=1&eee=2* @param: method 请求方式 get/post/put/delte等* @return: java.lang.String*/private static String open(String strURL, String params, String method) {try {URL url = new URL(strURL);// 创建连接HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setDoOutput(true);connection.setDoInput(true);connection.setUseCaches(false);connection.setInstanceFollowRedirects(true);connection.setRequestMethod(method);connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式connection.connect();OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);// utf-8编码out.append(params);out.flush();out.close(); // 读取响应int length = connection.getContentLength();// 获取长度InputStream is = connection.getInputStream();if (length != -1) {byte[] data = new byte[length];byte[] temp = new byte[512];int readLen = 0;int destPos = 0;while ((readLen = is.read(temp)) > 0) {System.arraycopy(temp, 0, data, destPos, readLen);destPos += readLen;}return new String(data, StandardCharsets.UTF_8);}} catch (Exception e) {e.printStackTrace();}return null;}/*** 向指定 URL 发送POST方法的请求** @param url   发送请求的 URL* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。* @return 所代表远程资源的响应结果*/public static String sendFile(String url, String param, String file) {if (url == null || param == null) {return url;}PrintWriter out = null;BufferedReader in = null;String result = "";try {URL realUrl = new URL(url);// 打开和URL之间的连接URLConnection conn = realUrl.openConnection();// 设置通用的请求属性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);//设置链接超时时间为2秒conn.setConnectTimeout(1000);//设置读取超时为2秒conn.setReadTimeout(1000);// 获取URLConnection对象对应的输出流out = new PrintWriter(conn.getOutputStream());out.write(file);// 发送请求参数out.print(param);// flush输出流的缓冲out.flush();// 定义BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println(e.getMessage() + "地址:" + url);return null;}//使用finally块来关闭输出流、输入流finally {try {if (out != null) {out.close();}if (in != null) {in.close();}} catch (IOException ex) {System.out.println(ex.getMessage());return null;}}return result;}/*** @param: filePath* @param: unit 单个文件大小* @return: 返回文件的目录*/private static File[] separate(Object obj, Integer unit) {try {InputStream bis = null;//输入流用于读取文件数据OutputStream bos = null;//输出流用于输出分片文件至磁盘File file = null;if (obj instanceof String) {file = new File((String) obj);}if (obj instanceof File) {file = (File) obj;}String filePath = file.getAbsolutePath();File newFile = new File(filePath.substring(0, filePath.lastIndexOf("\\") + 1));String directoryPath = newFile.getAbsolutePath();long splitSize = unit * 1024 * 1024;//单片文件大小,MBif (file.length() < splitSize) {log.info("文件小于单个分片大小,无需分片{}", file.length());return new File[]{file};}//分片二//RandomAccessFile in=null;//RandomAccessFile out =null;//long length=file.length();//文件大小//long count=length%splitSize==0?(length/splitSize):(length/splitSize+1);//文件分片数//byte[] bt=new byte[1024];//in=new RandomAccessFile(file, "r");//for (int i = 1; i <= count; i++) {//    out = new RandomAccessFile(new File(filePath+"."+i), "rw");//定义一个可读可写且后缀名为.part的二进制分片文件//    long begin = (i-1)*splitSize;//    long end = i* splitSize;//    int len=0;//    in.seek(begin);//    while (in.getFilePointer()<end&&-1!=(len=in.read(bt))) {//        out.write(bt, 0, len);//    }//    out.close();//}//分片一bis = new BufferedInputStream(new FileInputStream(file));long writeByte = 0;//已读取的字节数int len = 0;byte[] bt = new byte[1024];while (-1 != (len = bis.read(bt))) {if (writeByte % splitSize == 0) {if (bos != null) {bos.flush();bos.close();}bos = new BufferedOutputStream(new FileOutputStream(filePath + "." + (writeByte / splitSize + 1) + ".part"));}writeByte += len;bos.write(bt, 0, len);}log.info("文件分片成功!");//排除被分片的文件if (newFile.isDirectory()) {File[] files = newFile.listFiles();File[] resultFiles = new File[files.length - 1];int j = 0;for (int i = 0; i < files.length; i++) {if (!files[i].equals(file)) {resultFiles[j] = files[i];j++;}}return resultFiles;}bos.flush();bos.close();bis.close();return new File[0];} catch (Exception e) {log.info("文件分片失败!");e.printStackTrace();}return null;}//splitNum:要分几片,currentDir:分片后存放的位置,subSize:按多大分片public static File[] nioSpilt(Object object, int splitNum, String currentDir, double subSize) {try {File file = null;if (object instanceof String) {file = new File((String) object);}if (object instanceof String) {file = (File) object;}FileInputStream fis = new FileInputStream(file);FileChannel inputChannel = fis.getChannel();FileOutputStream fos;FileChannel outputChannel;long splitSize = (long) subSize;long startPoint = 0;long endPoint = splitSize;for (int i = 1; i <= splitNum; i++) {fos = new FileOutputStream(currentDir + i);outputChannel = fos.getChannel();inputChannel.transferTo(startPoint, splitSize, outputChannel);startPoint += splitSize;endPoint += splitSize;outputChannel.close();fos.close();}inputChannel.close();fis.close();File newFile = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("\\") + 1));if (newFile.isDirectory()) {return newFile.listFiles();}} catch (Exception e) {e.printStackTrace();}return new File[0];}/*** @Description: TODO 发送文件* @param: url 发送地址* @param: file 发送文件* @return: java.lang.String*/private static String sendFile(String url, File file) {try {MultipartEntityBuilder builder = MultipartEntityBuilder.create();builder.setContentType(ContentType.MULTIPART_FORM_DATA);builder.addBinaryBody("file", file);String body = "";//创建httpclient对象CloseableHttpClient client = HttpClients.createDefault();//创建post方式请求对象HttpPost httpPost = new HttpPost(url);//设置请求参数HttpEntity httpEntity = builder.build();httpPost.setEntity(httpEntity);//执行请求操作,并拿到结果(同步阻塞)CloseableHttpResponse response = client.execute(httpPost);//获取结果实体HttpEntity entity = response.getEntity();if (entity != null) {//按指定编码转换结果实体为String类型body = EntityUtils.toString(entity, "utf-8");}EntityUtils.consume(entity);//释放链接response.close();return body;} catch (Exception e) {e.printStackTrace();}return null;}}

JAVA实现百度网盘文件上传相关推荐

  1. linux登录百度网盘下载上传文件

    这里写自定义目录标题 linux登录百度网盘下载上传文件 linux登录百度网盘下载上传文件 参考一下的三个地址: 1.https://blog.csdn.net/huojiahui22/articl ...

  2. 百度网盘海外版上传下载不限速;一季度北京平均月薪达11187元;苹果 CEO 增加新候选人|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  3. linux命令行连接百度网盘快速上传下载数据(bypy)

    摘要 现在的深度学习代码基本都是在服务器上运行,而大部分的服务器都是远程服务器,只支持命令行操作,所以有些在图形界面上比较容易下载的文件,在服务器上使用命令行很难下载.而且由于远程服务器和本地之间数据 ...

  4. Google网盘 百度网盘文件互传-Multcloud

    MultCloud 是一款功能比较强大的网盘文件相互转存的在线工具,它支持的国外网盘较多,有Dropbox.Google Drive.Skydrive.Amazon S3.SugarSync.MEGA ...

  5. google网盘 百度网盘文件互传

    互传方法: 访问:https://www.multcloud.com/ 系统会自动分配一个账号.建议绑定邮箱,修改密码并激活. 如上图.点击添加云盘. 这里我需要在百度云盘和谷歌云盘之间传输文件.所以 ...

  6. 百度网盘如何上传超大文件?(超过4G)

    视频教程 如何上传到百度云大文件--优酷 使用压缩软件的设置分卷大小,每个文件在4g以下,就可以上传多个文件了. 需要用的时候再全部下载下来,解压的时候只需要解压下图中任意一个文件就可以了. 转载自百 ...

  7. 文件上载限制4gb_新get!百度网盘破除上传单个文件超4GB限制

    现在网盘的限制是越来越多,国内还在免费+能用的也就剩百度网盘了.虽然随便注册个账号大家都能凑合用用,但非会员5GB的使用空间.上传/下载速率限制,加上下载大文件必须使用网盘客户端等,让小编发现百度网盘 ...

  8. Java仿百度网盘,拿来学习/搞外快,都是极好的选择

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 一.前言 ...

  9. Linux 下载百度网盘文件

    Linux 下载百度网盘文件 1. 准备环境: centos7.2 python2.7+ pip 2. 安装工具 pip install requests -i https://pypi.douban ...

  10. 2021年4月如何加速下载百度网盘文件,分享个不限速的内部体验版

    苏生不惑第240 篇原创文章,将本公众号设为星标,第一时间看最新文章. 关于百度网盘之前分享过很多文章了: 2020 年 3 月最新加速下载百度网盘文件方法 2020 最全百度网盘搜索,找电影资源不再 ...

最新文章

  1. 定制一个自己想要的搜索页面
  2. Yii2的深入学习--yii\base\Object 类
  3. 一个按钮触发两个事件可以吗?
  4. [MicroPython]TurnipBit开发板旋转按钮控制直流电机转速
  5. 什么是protobuf
  6. 快速制作U盘WIN PE启动盘简易指南
  7. hdoj 1015 Safecracker
  8. socket通信基础
  9. STL—内存的配置与释放
  10. Tomcat报错:The server does not support version 3.0 of the J2EE Web module specification
  11. VirtualBox 虚拟 CentOS 7 磁盘扩容
  12. 一次领光天猫双 11 所有优惠卷
  13. android studio安卓订餐管理系统
  14. linux 火狐 jre插件,[原]再谈Firefox安装java插件的问题
  15. [COGS2287][HZOI 2015]疯狂的机器人(NTT)
  16. 《玩透嵌入式C的角角落落》深入分析sprintf和printf函数
  17. H5调用Android原生Api
  18. 人工智能的前景 | 钱颖一对话张首晟、饶毅、马化腾
  19. 具体的数据库存储过程的编写
  20. list of questions

热门文章

  1. 第四届IT 2020高端论坛成功举办
  2. [038]量化交易]显示所有股票名称及股票代码
  3. java 扫描tcp端口号_Java 端口扫描器 TCP的实现方法
  4. 名词解释微型计算机,微机原理名词解释
  5. 服务器管理口IP及账号密码(知识汇总)
  6. 模拟信号数字化的过程(一)——采样和量化
  7. 2017-2018-2 20155314《网络对抗技术》Exp4 恶意代码分析
  8. github releases一直失败的解决方案
  9. java过滤器的作用_javaweb过滤器的作用,过滤器filter的作用是什么?
  10. 237. 删除链表中的节点 (Delete Node in a Linked List)