Java代码实现百度网盘上传文件并自动刷新token

来源于  :https://blog.csdn.net/m0_64980357/article/details/130560193

 这是主要的的目录结构:

 

这段代码主体是AutoUploadFile,把文件放到某一目录下名称格式为日期类型eg:2022-11-13然后修改配置文件的文件存放地址就可以自动上传文件(可以自己修改),其他配置如refreshToken可以去百度网盘开放平台(https://pan.baidu.com/union/doc/)查看如何获取;

1.AutoRefreshToken:用来自动刷新token

代码如下:

 
  1.  
    package com.example.demo.apps;
  2.  
  3.  
  4.  
    import com.alibaba.fastjson.JSON;
  5.  
    import org.apache.http.HttpResponse;
  6.  
  7.  
    import org.apache.http.client.HttpClient;
  8.  
    import org.apache.http.client.methods.HttpGet;
  9.  
    import org.apache.http.impl.client.HttpClientBuilder;
  10.  
    import org.apache.http.util.EntityUtils;
  11.  
    import org.jsoup.nodes.Document;
  12.  
    import org.jsoup.nodes.Element;
  13.  
    import org.springframework.beans.factory.annotation.Value;
  14.  
    import org.springframework.stereotype.Component;
  15.  
  16.  
    import java.io.IOException;
  17.  
    import java.io.BufferedReader;
  18.  
    import java.io.InputStream;
  19.  
    import java.io.InputStreamReader;
  20.  
    import java.net.HttpURLConnection;
  21.  
    import java.net.URL;
  22.  
    import java.net.URLEncoder;
  23.  
    import java.util.Map;
  24.  
    import java.util.UUID;
  25.  
  26.  
    import org.apache.http.impl.client.CloseableHttpClient;
  27.  
    import org.apache.http.impl.client.HttpClients;
  28.  
    import com.alibaba.fastjson.JSONObject;
  29.  
    import org.jsoup.*;
  30.  
  31.  
  32.  
    /**
  33.  
    * @date 日期:2023/5/6 时间:11:57
  34.  
    * @Description: 自动刷新token
  35.  
    */
  36.  
    @Component
  37.  
    public class AutoRefreshToken {
  38.  
    /* public static void main(String[] args) {
  39.  
    try {
  40.  
    String atoken = getAtoken();
  41.  
    System.out.println(atoken);
  42.  
    } catch (Exception e) {
  43.  
    e.printStackTrace();
  44.  
    }
  45.  
    }*/
  46.  
  47.  
    @Value("${Constant.APP_KEY}")
  48.  
    String APP_KEY;
  49.  
    @Value("${Constant.SECRET_KEY}")
  50.  
    String SECRET_KEY;
  51.  
    @Value("${Constant.refresh_token}")
  52.  
    String refresh_token;
  53.  
  54.  
    @Value("${Constant.APP_ID}")
  55.  
    String APP_ID;
  56.  
  57.  
    /* public static void main(String[] args) throws Exception {
  58.  
    String atoken = getAtoken();
  59.  
    System.out.println(atoken);
  60.  
    }*/
  61.  
  62.  
  63.  
    public String getAtoken() throws Exception {
  64.  
  65.  
    String url1 = "https://openapi.baidu.com/oauth/2.0/token?" +
  66.  
    "grant_type=refresh_token&" +
  67.  
    "refresh_token=" + refresh_token +
  68.  
    "&client_id=" + APP_KEY +
  69.  
    "&client_secret=" + SECRET_KEY;
  70.  
    /* String url1="https://openapi.baidu.com/oauth/2.0/token?" +
  71.  
    "grant_type=refresh_token&" +
  72.  
    "refresh_token=122.abf06f23035add703f92eecac6eb4919.YaIson6QQF9KmCuw7pQ6wPUWDY16KsK1V8bg9Rw.6Dv_WA&" +
  73.  
    "client_id=fBulUWK7sTZo3s94gYSPveov9qsaq5LE&" +
  74.  
    "client_secret=eapgT5k4XXmRRgfxxlcxR82e3gursVze";*/
  75.  
  76.  
    try {
  77.  
    URL url = new URL(url1);
  78.  
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  79.  
    conn.setRequestMethod("GET");
  80.  
    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  81.  
    String inputLine;
  82.  
    StringBuffer response = new StringBuffer();
  83.  
    while ((inputLine = in.readLine()) != null) {
  84.  
    response.append(inputLine);
  85.  
    }
  86.  
    in.close();
  87.  
    // System.out.println(response.toString());
  88.  
    Map map = JSON.parseObject(response.toString(), Map.class);
  89.  
    String atoken = (String) map.get("access_token");
  90.  
    // Return the atoken
  91.  
    return atoken;
  92.  
    } catch (Exception e) {
  93.  
    System.out.println(e);
  94.  
    }
  95.  
    return "触发安全协议";
  96.  
    }
  97.  
  98.  
  99.  
    }
 
 

2.AutoUploadFile:用来上传文件

代码如下: 

 
  1.  
    package com.example.demo.apps;
  2.  
  3.  
  4.  
    import cn.hutool.http.HttpUtil;
  5.  
    import cn.hutool.json.JSONArray;
  6.  
    import cn.hutool.json.JSONObject;
  7.  
    import com.alibaba.fastjson.JSON;
  8.  
    import com.fasterxml.jackson.databind.ObjectMapper;
  9.  
    import org.apache.http.HttpEntity;
  10.  
    import org.apache.http.client.methods.CloseableHttpResponse;
  11.  
    import org.apache.http.client.methods.HttpPost;
  12.  
    import org.apache.http.entity.ContentType;
  13.  
    import org.apache.http.entity.mime.MultipartEntityBuilder;
  14.  
    import org.apache.http.impl.client.CloseableHttpClient;
  15.  
    import org.apache.http.impl.client.HttpClients;
  16.  
    import org.apache.http.util.EntityUtils;
  17.  
    import org.slf4j.Logger;
  18.  
    import org.slf4j.LoggerFactory;
  19.  
    import org.springframework.beans.factory.annotation.Autowired;
  20.  
    import org.springframework.beans.factory.annotation.Value;
  21.  
    import org.springframework.scheduling.annotation.Scheduled;
  22.  
    import org.springframework.stereotype.Component;
  23.  
  24.  
    import java.io.*;
  25.  
    import java.net.HttpURLConnection;
  26.  
    import java.net.URL;
  27.  
    import java.net.URLConnection;
  28.  
    import java.nio.channels.FileChannel;
  29.  
    import java.nio.charset.StandardCharsets;
  30.  
    import java.security.MessageDigest;
  31.  
    import java.text.SimpleDateFormat;
  32.  
    import java.util.*;
  33.  
    import java.io.File;
  34.  
    import java.io.IOException;
  35.  
  36.  
    /**
  37.  
    * @date 日期:2023/4/26 时间:09:57
  38.  
    * @Description: 上传文件到百度网盘
  39.  
    */
  40.  
     
  41.  
    @Component
  42.  
    public class AutoUploadFile {
  43.  
  44.  
    @Autowired
  45.  
    private SendEamil sendEamil;
  46.  
    //操作文件 copy, mover, rename, delete
  47.  
    String FILE_MANAGER_URL = " https://pan.baidu.com/rest/2.0/xpan/file";
  48.  
    //预上传
  49.  
    String GET_READY_FILE_URL = "https://pan.baidu.com/rest/2.0/xpan/file";
  50.  
    //分片上传
  51.  
    String SLICING_UPLOAD_FILE_URL = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2";
  52.  
    //下载文件
  53.  
    String DOWN_LOUE_URL = "https://pan.baidu.com/rest/2.0/xpan/multimedia";
  54.  
    //文件搜索
  55.  
    String FILE_SEARCH = "https://pan.baidu.com/rest/2.0/xpan/file?method=search";
  56.  
    Logger logger = LoggerFactory.getLogger(getClass());
  57.  
    //失败重试计数器
  58.  
    int num = 0;
  59.  
    //分片大小
  60.  
    @Value("${Constant.UNIT}")
  61.  
    Integer UNIT;
  62.  
    //获取到的授权码
  63.  
    /* @Value("${Constant.CODE}")
  64.  
    String CODE;
  65.  
    @Value("${Constant.filePath}")
  66.  
    String filePath;*/
  67.  
  68.  
    @Value("${Constant.APP_ID}")
  69.  
    String APP_ID;
  70.  
    @Value("${Constant.APP_NAME}")
  71.  
    String APP_NAME;
  72.  
    @Value("${Constant.APP_KEY}")
  73.  
    String APP_KEY;
  74.  
    @Value("${Constant.SECRET_KEY}")
  75.  
    String SECRET_KEY;
  76.  
    @Autowired
  77.  
    private AutoRefreshToken autoRefreshToken;
  78.  
    //@Value("${Constant.ATOKEN}")
  79.  
    String ATOKEN;
  80.  
  81.  
  82.  
    @Value("${Constant.filePath}")
  83.  
    String filePath;
  84.  
    @Value("${Eamil.userName}")
  85.  
    String userName;
  86.  
    String fileName;
  87.  
  88.  
    /*
  89.  
    * 自动刷新token
  90.  
    * token每月过期一次
  91.  
    * 通过定时任务每月刷新一次*/
  92.  
    @Scheduled(cron = "${scheduling.getAtoken}")
  93.  
    public void flushToken() {
  94.  
    try {
  95.  
    Properties prop = new Properties();
  96.  
    String atoken1 = autoRefreshToken.getAtoken();
  97.  
    prop.setProperty("ATOKEN", atoken1);
  98.  
    FileWriter writer = new FileWriter("token.properties");
  99.  
    prop.store(writer, "Optional header comment");
  100.  
    writer.close();
  101.  
    } catch (Exception e) {
  102.  
    e.printStackTrace();
  103.  
    }
  104.  
    }
  105.  
  106.  
    /**
  107.  
    * @Description: TODO 保存文件
  108.  
    * @param: filePath 文件路径
  109.  
    * @param: fileName 文件名称
  110.  
    * return 文件下载地址
  111.  
    */
  112.  
     
  113.  
    @Scheduled(cron = "${scheduling.executionTime}")
  114.  
    public void save() throws Exception {
  115.  
    getToken();
  116.  
  117.  
    Date date = new Date();
  118.  
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
  119.  
    String formattedDate = formatter.format(date);
  120.  
    File folder = new File(filePath);
  121.  
    File[] files = folder.listFiles();
  122.  
  123.  
    for (File file : files) {
  124.  
    String fileName1 = file.getName();
  125.  
    boolean contains = fileName1.contains(formattedDate);
  126.  
    if (contains) {
  127.  
    fileName = fileName1;
  128.  
    }
  129.  
    }
  130.  
    if (fileName == null) {
  131.  
    logger.info("文件不存在 !");
  132.  
    return;
  133.  
    }
  134.  
    logger.info("正在上传文件为" + fileName);
  135.  
  136.  
    //本地文件地址
  137.  
    String absoluteFilePath = filePath + fileName;
  138.  
    logger.info("本地文件地址" + absoluteFilePath);
  139.  
    //云端文件地址
  140.  
    String cloudPath = "/apps/" + APP_NAME + "/";
  141.  
    logger.info("文件在百度网盘的存放位置" + cloudPath);
  142.  
    //文件分片并获取md5
  143.  
    File file = new File(absoluteFilePath);
  144.  
    File[] separate = separate(absoluteFilePath, UNIT);
  145.  
  146.  
    StringBuffer md5s = new StringBuffer();
  147.  
    if (separate.length == 1) {
  148.  
    md5s.append(getMD5(separate[0]));
  149.  
    }
  150.  
    //long length1 = file.length();
  151.  
    //long length=0;
  152.  
    if (separate.length > 1) {
  153.  
    for (int i = 0; i < separate.length; i++) {
  154.  
    md5s.append(getMD5(separate[i]) + "\",\"");
  155.  
  156.  
    logger.info("正在分片,{}{}" + separate[i].toString() + ">>>" + i);
  157.  
    //length += separate[i].length();
  158.  
    }
  159.  
    String s = md5s.toString();
  160.  
    md5s = new StringBuffer(s.substring(0, md5s.length() - 3));
  161.  
    }
  162.  
  163.  
    //预上传
  164.  
    String precreate = precreate(cloudPath, file.length(), 0, md5s.toString());
  165.  
  166.  
    logger.info("预上传{}" + precreate);
  167.  
    String uploadid = (String) new JSONObject(precreate).get("uploadid");
  168.  
    //分片上传
  169.  
    String upload = upload(cloudPath, (String) new JSONObject(precreate).get("uploadid"), separate);
  170.  
    logger.info("分片上传{}" + upload);
  171.  
    //创建文件
  172.  
    // String create = folderMerge("/apps/" + APP_NAME, file.length(), list.toString(),uploadid);
  173.  
    String create = create(fileName, file.length(), 0, md5s.toString(), uploadid);
  174.  
  175.  
    logger.info("创建文件{}" + create);
  176.  
  177.  
    //删除解压后文件
  178.  
    File directory2 = new File(filePath);
  179.  
    File[] files2 = directory2.listFiles();
  180.  
    for (File file2 : files2) {
  181.  
    if (file2.isFile() && file2.getName().contains("part")) {
  182.  
    file2.delete();
  183.  
    }
  184.  
    }
  185.  
    logger.info("解压后文件已经清除!");
  186.  
  187.  
    ObjectMapper objectMapper = new ObjectMapper();
  188.  
    Map<String, Object> map = objectMapper.readValue(create, Map.class);
  189.  
    Integer errno = (Integer) map.get("errno");
  190.  
    if (errno != 0) {
  191.  
    //发送失败3次后发送信息到邮箱
  192.  
    if (num == 3) {
  193.  
    sendEamil.sendMail(create + "时间为" + formattedDate);
  194.  
    logger.info("上传出现问题,已发送邮件到>>>" + userName);
  195.  
    }
  196.  
    num++;
  197.  
    save();
  198.  
    }
  199.  
  200.  
    }
  201.  
  202.  
    private void getToken() throws IOException {
  203.  
    //读取token
  204.  
    Properties prop = new Properties();
  205.  
    FileInputStream fileInputStream = new FileInputStream("token.properties");
  206.  
    prop.load(fileInputStream);
  207.  
    String atoken = prop.getProperty("ATOKEN");
  208.  
    if (atoken == null || atoken.equals("")) {
  209.  
    flushToken();
  210.  
    getToken();
  211.  
    }
  212.  
    ATOKEN = atoken;
  213.  
    fileInputStream.close();
  214.  
    logger.info("accessToken值为>>>" + ATOKEN);
  215.  
    }
  216.  
  217.  
  218.  
    /**
  219.  
    * @Description: TODO 获取下载地址
  220.  
    * @param: fileName 文件名
  221.  
    */
  222.  
    public String getDownUrl(String fileName) {
  223.  
    String fileSearch = HttpUtil.get(FILE_SEARCH + "&access_token=" + ATOKEN + "&key=" + fileName);
  224.  
    JSONObject jsonObject = new JSONObject(fileSearch);
  225.  
    JSONArray list = jsonObject.getJSONArray("list");
  226.  
    JSONObject listJSONObject = list.getJSONObject(0);
  227.  
    Long fs_id = listJSONObject.getLong("fs_id");
  228.  
    String url = DOWN_LOUE_URL + "?method=filemetas&access_token=" + ATOKEN + "&fsids=[" + fs_id + "]&dlink=1";
  229.  
    String s = HttpUtil.get(url);
  230.  
    JSONObject sJsonObject = new JSONObject(s);
  231.  
    JSONArray jsonArray = sJsonObject.getJSONArray("list");
  232.  
    JSONObject jsonObjectClient = jsonArray.getJSONObject(0);
  233.  
    String dlink = jsonObjectClient.getStr("dlink");
  234.  
    return dlink;
  235.  
    }
  236.  
  237.  
    /**
  238.  
    * @Description: TODO 创建文件
  239.  
    * @param: fileName 文件名称
  240.  
    * @param: size 文件大小 字节
  241.  
    * @param: isDir 0文件 1目录(设置为目录是 size要设置为0)
  242.  
    * @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传
  243.  
    * @return: java.lang.String
  244.  
    */
  245.  
    public String create(String fileName, Long size, Integer isDir, String blockList, String uploadId) {
  246.  
    String strURL = FILE_MANAGER_URL + "?method=create&access_token=" + ATOKEN;
  247.  
    String params = "path=" + "/apps/" + APP_NAME + "/" + fileName + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir + "&uploadid=" + uploadId + "&rtype=3";
  248.  
    return openTest(strURL, params, "POST");
  249.  
    // "https://pan.baidu.com/rest/2.0/xpan/file?method=create&access_token="
  250.  
    //'&rtype=3&uploadid==&block_list=["7d57c40c9fdb4e4a32d533bee1a4e409"]'
  251.  
    }
  252.  
  253.  
    /**
  254.  
    * @Description: TODO 分片上传
  255.  
    * @param: path 上传到百度网盘的地址
  256.  
    * @param: uploadid 上传的id
  257.  
    * @param: filePath 本地文件的地址
  258.  
    * @return: java.lang.String
  259.  
    */
  260.  
    public String upload(String path, String uploadid, File[] files) {
  261.  
  262.  
    try {
  263.  
  264.  
    for (int i = 0; i < files.length; i++) {
  265.  
  266.  
    String url = SLICING_UPLOAD_FILE_URL + "?method=upload" +
  267.  
    "&access_token=" + ATOKEN +
  268.  
    "&type=tmpfile&partseq=" + i +
  269.  
    "&path=" + path +
  270.  
    "&uploadid=" + uploadid;
  271.  
  272.  
    String s = sendFile(url, files[i]);
  273.  
  274.  
    logger.info("正在上传分片文件{}{}" + s + i);
  275.  
  276.  
    }
  277.  
    return path;
  278.  
    } catch (Exception e) {
  279.  
    e.printStackTrace();
  280.  
    }
  281.  
    return null;
  282.  
    }
  283.  
  284.  
  285.  
    /**
  286.  
    * @Description: TODO 预上传
  287.  
    * @param: cloudPath 云端路径
  288.  
    * @param: size 文件大小 字节
  289.  
    * @param: isDir 0文件 1目录(设置为目录是 size要设置为0)
  290.  
    * @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传
  291.  
    * @return: java.lang.String
  292.  
    */
  293.  
    public String precreate(String cloudPath, Long size, Integer isDir, String blockList) {
  294.  
    String strURL = GET_READY_FILE_URL + "?method=precreate&access_token=" + ATOKEN;
  295.  
    String params = "path=" + cloudPath + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir;
  296.  
    return openTest(strURL, params, "POST");
  297.  
  298.  
    }
  299.  
  300.  
  301.  
    /**
  302.  
    * @Description: TODO 获取md5值
  303.  
    * String path 文件地址
  304.  
    */
  305.  
    private final static String[] strHex = {"0", "1", "2", "3", "4", "5",
  306.  
    "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
  307.  
  308.  
    private static String getMD5(File path) {
  309.  
    StringBuilder buffer = new StringBuilder();
  310.  
    try {
  311.  
    MessageDigest md = MessageDigest.getInstance("MD5");
  312.  
    byte[] b = md.digest(org.apache.commons.io.FileUtils.readFileToByteArray(path));
  313.  
    for (int value : b) {
  314.  
    int d = value;
  315.  
    if (d < 0) {
  316.  
    d += 256;
  317.  
    }
  318.  
    int d1 = d / 16;
  319.  
    int d2 = d % 16;
  320.  
    buffer.append(strHex[d1]).append(strHex[d2]);
  321.  
    }
  322.  
    return buffer.toString();
  323.  
    } catch (Exception e) {
  324.  
    return null;
  325.  
    }
  326.  
    }
  327.  
  328.  
  329.  
    /**
  330.  
    * @Description: TODO
  331.  
    * @param: strURL 网址,可以是 http://aaa?bbb=1&ccc=2 拼接的
  332.  
    * @param: params 拼接的body参数也就是form表单的参数 ddd=1&eee=2
  333.  
    * @param: method 请求方式 get/post/put/delte等
  334.  
    * @return: java.lang.String
  335.  
    */
  336.  
    public String open(String strURL, String params, String method) {
  337.  
    try {
  338.  
    URL url = new URL(strURL);// 创建连接
  339.  
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  340.  
    connection.setDoOutput(true);
  341.  
    connection.setDoInput(true);
  342.  
    connection.setUseCaches(false);
  343.  
    connection.setInstanceFollowRedirects(true);
  344.  
    connection.setRequestMethod(method);
  345.  
    connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式
  346.  
    connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式
  347.  
    connection.connect();
  348.  
  349.  
    OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);// utf-8编码
  350.  
    out.append(params);
  351.  
    out.flush();
  352.  
    out.close(); // 读取响应
  353.  
    int length = connection.getContentLength();// 获取长度
  354.  
    InputStream is = connection.getInputStream();
  355.  
    if (length != -1) {
  356.  
    byte[] data = new byte[length];
  357.  
    byte[] temp = new byte[512];
  358.  
    int readLen = 0;
  359.  
    int destPos = 0;
  360.  
    while ((readLen = is.read(temp)) > 0) {
  361.  
    System.arraycopy(temp, 0, data, destPos, readLen);
  362.  
    destPos += readLen;
  363.  
    }
  364.  
    return new String(data, StandardCharsets.UTF_8);
  365.  
    }
  366.  
    } catch (Exception e) {
  367.  
    e.printStackTrace();
  368.  
    }
  369.  
    return null;
  370.  
    }
  371.  
  372.  
  373.  
    /**
  374.  
    * 向指定 URL 发送POST方法的请求
  375.  
    *
  376.  
    * @param url 发送请求的 URL
  377.  
    * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
  378.  
    * @return 所代表远程资源的响应结果
  379.  
    */
  380.  
    public String sendFile(String url, String param, String file) {
  381.  
    if (url == null || param == null) {
  382.  
    return url;
  383.  
    }
  384.  
  385.  
    PrintWriter out = null;
  386.  
    BufferedReader in = null;
  387.  
    String result = "";
  388.  
    try {
  389.  
    URL realUrl = new URL(url);
  390.  
    // 打开和URL之间的连接
  391.  
    URLConnection conn = realUrl.openConnection();
  392.  
    // 设置通用的请求属性
  393.  
    conn.setRequestProperty("accept", "*/*");
  394.  
    conn.setRequestProperty("connection", "Keep-Alive");
  395.  
    conn.setRequestProperty("user-agent",
  396.  
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
  397.  
  398.  
    // 发送POST请求必须设置如下两行
  399.  
    conn.setDoOutput(true);
  400.  
    conn.setDoInput(true);
  401.  
    //设置链接超时时间为2
  402.  
    conn.setConnectTimeout(1000);
  403.  
    //设置读取超时为2
  404.  
    conn.setReadTimeout(1000);
  405.  
    // 获取URLConnection对象对应的输出流
  406.  
    out = new PrintWriter(conn.getOutputStream());
  407.  
    out.write(file);
  408.  
    // 发送请求参数
  409.  
    out.print(param);
  410.  
    // flush输出流的缓冲
  411.  
    out.flush();
  412.  
    // 定义BufferedReader输入流来读取URL的响应
  413.  
    in = new BufferedReader(
  414.  
    new InputStreamReader(conn.getInputStream()));
  415.  
    String line;
  416.  
    while ((line = in.readLine()) != null) {
  417.  
    result += line;
  418.  
    }
  419.  
    } catch (Exception e) {
  420.  
    System.out.println(e.getMessage() + "地址:" + url);
  421.  
    return null;
  422.  
    }
  423.  
    //使用finally块来关闭输出流、输入流
  424.  
    finally {
  425.  
    try {
  426.  
    if (out != null) {
  427.  
    out.close();
  428.  
    }
  429.  
    if (in != null) {
  430.  
    in.close();
  431.  
    }
  432.  
    } catch (IOException ex) {
  433.  
    System.out.println(ex.getMessage());
  434.  
    return null;
  435.  
    }
  436.  
    }
  437.  
    return result;
  438.  
    }
  439.  
  440.  
  441.  
    /**
  442.  
    * @param: filePath
  443.  
    * @param: unit 单个文件大小
  444.  
    * @return: 返回文件的目录
  445.  
    */
  446.  
    public File[] separate(Object obj, Integer unit) {
  447.  
  448.  
    try {
  449.  
  450.  
    InputStream bis = null;//输入流用于读取文件数据
  451.  
    OutputStream bos = null;//输出流用于输出分片文件至磁盘
  452.  
    File file = null;
  453.  
    if (obj instanceof String) {
  454.  
    file = new File((String) obj);
  455.  
    }
  456.  
    if (obj instanceof File) {
  457.  
    file = (File) obj;
  458.  
    }
  459.  
    String filePath = file.getAbsolutePath();
  460.  
  461.  
    File newFile = new File(filePath.substring(0, filePath.lastIndexOf("\\") + 1));
  462.  
  463.  
    String directoryPath = newFile.getAbsolutePath();
  464.  
    long splitSize = unit * 1024 * 1024;//单片文件大小,MB
  465.  
    if (file.length() < splitSize) {
  466.  
    // log.info("文件小于单个分片大小,无需分片{}", file.length());
  467.  
    // System.out.println();
  468.  
    logger.info("文件小于单个分片大小,无需分片{}" + file.length());
  469.  
    return new File[]{file};
  470.  
    }
  471.  
  472.  
    long length = file.length();
  473.  
    long splitNum = (length / splitSize);
  474.  
    if (length % splitSize != 0) {
  475.  
    splitNum++;
  476.  
    }
  477.  
    //todo 分片
  478.  
    FileInputStream fis = new FileInputStream(filePath);
  479.  
    FileChannel inputChannel = fis.getChannel();
  480.  
    FileOutputStream fos;
  481.  
    FileChannel outputChannel;
  482.  
    File currentDirFile = new File(filePath);
  483.  
    if (!currentDirFile.exists()) {
  484.  
    currentDirFile.mkdirs();
  485.  
    }
  486.  
    long startPoint = 0;
  487.  
    for (int i = 1; i <= (int) splitNum; i++) {
  488.  
    String splitFileName = filePath + i;
  489.  
    fos = new FileOutputStream(filePath + "." + i + ".part");
  490.  
    outputChannel = fos.getChannel();
  491.  
    inputChannel.transferTo(startPoint, splitSize, outputChannel);
  492.  
    startPoint += splitSize;
  493.  
    outputChannel.close();
  494.  
    fos.close();
  495.  
    }
  496.  
    inputChannel.close();
  497.  
  498.  
  499.  
  500.  
  501.  
    logger.info("文件分片成功!");
  502.  
    //排除被分片的文件
  503.  
    if (newFile.isDirectory()) {
  504.  
    File[] files = newFile.listFiles();
  505.  
    int num = 0;
  506.  
    for (int i = 0; i < files.length; i++) {
  507.  
    if (files[i].getName().contains("part")) {
  508.  
  509.  
    /* File srcFile = FileUtil.file(files[i].getPath());
  510.  
    //目标目录不存在程序也会帮忙创建
  511.  
    File destFile = FileUtil.file("d://DB_test");
  512.  
    FileUtil.move(srcFile, destFile, true);*/
  513.  
  514.  
    num++;
  515.  
    }
  516.  
  517.  
    }
  518.  
    File[] resultFiles = new File[num];
  519.  
    int j = 0;
  520.  
    for (int i = 0; i < files.length; i++) {
  521.  
    //!files[i].equals(file)
  522.  
    if (files[i].getName().contains("part")) {
  523.  
    resultFiles[j] = files[i];
  524.  
    j++;
  525.  
    }
  526.  
    }
  527.  
  528.  
  529.  
    return resultFiles;
  530.  
    }
  531.  
  532.  
    bos.flush();
  533.  
    bos.close();
  534.  
    bis.close();
  535.  
    return new File[0];
  536.  
    } catch (Exception e) {
  537.  
  538.  
    logger.info("文件分片失败!");
  539.  
    e.printStackTrace();
  540.  
    }
  541.  
    return null;
  542.  
    }
  543.  
  544.  
    //splitNum:要分几片,currentDir:分片后存放的位置,subSize:按多大分片
  545.  
    public File[] nioSpilt(Object object, int splitNum, String currentDir, double subSize) {
  546.  
    try {
  547.  
    File file = null;
  548.  
    if (object instanceof String) {
  549.  
    file = new File((String) object);
  550.  
    }
  551.  
    if (object instanceof String) {
  552.  
    file = (File) object;
  553.  
    }
  554.  
    FileInputStream fis = new FileInputStream(file);
  555.  
    FileChannel inputChannel = fis.getChannel();
  556.  
    FileOutputStream fos;
  557.  
    FileChannel outputChannel;
  558.  
    long splitSize = (long) subSize;
  559.  
    long startPoint = 0;
  560.  
    long endPoint = splitSize;
  561.  
    for (int i = 1; i <= splitNum; i++) {
  562.  
    fos = new FileOutputStream(currentDir + i);
  563.  
    outputChannel = fos.getChannel();
  564.  
    inputChannel.transferTo(startPoint, splitSize, outputChannel);
  565.  
    startPoint += splitSize;
  566.  
    endPoint += splitSize;
  567.  
    outputChannel.close();
  568.  
    fos.close();
  569.  
    }
  570.  
    inputChannel.close();
  571.  
    fis.close();
  572.  
    File newFile = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("\\") + 1));
  573.  
    if (newFile.isDirectory()) {
  574.  
    return newFile.listFiles();
  575.  
    }
  576.  
    } catch (Exception e) {
  577.  
    e.printStackTrace();
  578.  
    }
  579.  
    return new File[0];
  580.  
    }
  581.  
  582.  
    /**
  583.  
    * @Description: TODO 发送文件
  584.  
    * @param: url 发送地址
  585.  
    * @param: file 发送文件
  586.  
    * @return: java.lang.String
  587.  
    */
  588.  
    public String sendFile(String url, File file) {
  589.  
    try {
  590.  
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
  591.  
    builder.setContentType(ContentType.MULTIPART_FORM_DATA);
  592.  
    builder.addBinaryBody("file", file);
  593.  
    String body = "";
  594.  
    //创建httpclient对象
  595.  
    CloseableHttpClient client = HttpClients.createDefault();
  596.  
    //创建post方式请求对象
  597.  
    HttpPost httpPost = new HttpPost(url);
  598.  
    //设置请求参数
  599.  
    HttpEntity httpEntity = builder.build();
  600.  
    httpPost.setEntity(httpEntity);
  601.  
  602.  
  603.  
    //执行请求操作,并拿到结果(同步阻塞)
  604.  
    CloseableHttpResponse response = client.execute(httpPost);
  605.  
  606.  
    //获取结果实体
  607.  
    HttpEntity entity = response.getEntity();
  608.  
    if (entity != null) {
  609.  
    //按指定编码转换结果实体为String类型
  610.  
    body = EntityUtils.toString(entity, "utf-8");
  611.  
    }
  612.  
    EntityUtils.consume(entity);
  613.  
    //释放链接
  614.  
  615.  
    response.close();
  616.  
    return body;
  617.  
    } catch (Exception e) {
  618.  
    e.printStackTrace();
  619.  
    }
  620.  
    return null;
  621.  
    }
  622.  
  623.  
  624.  
    public String openTest(String strURL, String params, String method) {
  625.  
    logger.info(strURL);
  626.  
    logger.info(params);
  627.  
    StringBuffer response = null;
  628.  
    try {
  629.  
    URL url = new URL(strURL);// 创建连接
  630.  
    HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
  631.  
    httpConn.setRequestMethod("POST");
  632.  
    httpConn.setRequestProperty("User-Agent", "pan.baidu.com");
  633.  
    httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  634.  
    httpConn.setDoOutput(true);
  635.  
  636.  
    OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
  637.  
    writer.write(params);
  638.  
  639.  
    writer.flush();
  640.  
    writer.close();
  641.  
    httpConn.getOutputStream().close();
  642.  
  643.  
    int responseCode = httpConn.getResponseCode();
  644.  
    System.out.println("Response Code : " + responseCode);
  645.  
    BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
  646.  
    String inputLine;
  647.  
    response = new StringBuffer();
  648.  
    while ((inputLine = in.readLine()) != null) {
  649.  
    response.append(inputLine);
  650.  
    }
  651.  
  652.  
    in.close();
  653.  
    System.out.println(response.toString());
  654.  
    } catch (Exception e) {
  655.  
    System.out.println(e);
  656.  
    }
  657.  
    return response == null ? null : response.toString();
  658.  
    }
  659.  
  660.  
    /**
  661.  
    * 分片上传
  662.  
    *
  663.  
    * @param file 上传的文件内容
  664.  
    * @param path 上传后使用的文件绝对路径,需要urlencode
  665.  
    * @param uploadid precreate接口下发的uploadid
  666.  
    * @param partseq 文件分片的位置序号,从0开始,参考precreate接口返回的block_list
  667.  
    * @return
  668.  
    */
  669.  
    public String slicingUpload(String file, String path, String uploadid, int partseq) throws Exception {
  670.  
  671.  
    // todo
  672.  
    // 请求url
  673.  
    String url = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?" + "&app_id=" + APP_ID + "&access_token=" + ATOKEN + "&method=upload&type=tmpfile" + "&path=" + path + "&uploadid=" + uploadid + "&partseq=" + partseq;
  674.  
    // "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?method=upload&access_token=xxx&path=/apps/test/test.jpg&type=tmpfile&uploadid=N1-NjEuMTM1LjE2OS44NDoxNTk2MTExNTczOjQ5MTMzMjgwNjk3MDYxODg3MzQ=&partseq=0"
  675.  
    Map<String, Object> map = new HashMap<>();
  676.  
    map.put("file", new File(file));
  677.  
    try {
  678.  
  679.  
    String result = HttpUtil.post(url, map);
  680.  
  681.  
    System.out.println(result);
  682.  
    return result;
  683.  
  684.  
    } catch (Exception e) {
  685.  
    e.printStackTrace();
  686.  
    }
  687.  
    return null;
  688.  
    }
  689.  
  690.  
    /**
  691.  
    * 创建文件 用于将多个分片合并成一个文件,完成文件的上传。
  692.  
    * 备注:可以使用该接口创建文件夹。
  693.  
    *
  694.  
    * @return
  695.  
    */
  696.  
    public String folderMerge(String filePath, Long size, String blockList, String uploadid) {
  697.  
    //百度网盘token
  698.  
    String accessToken = ATOKEN;
  699.  
    // 请求url
  700.  
    String url = "https://pan.baidu.com/rest/2.0/xpan/file?method=create" + "&access_token=" + accessToken;
  701.  
  702.  
    try {
  703.  
    Map<String, Object> map = new HashMap<>();
  704.  
    //todo
  705.  
    map.put("path", filePath);
  706.  
    map.put("size", size);
  707.  
    map.put("isdir", 0);
  708.  
    map.put("block_list", blockList);
  709.  
    map.put("uploadid", uploadid);
  710.  
    String result = HttpUtil.post(url, map);
  711.  
    System.out.println(result);
  712.  
    return result;
  713.  
    } catch (Exception e) {
  714.  
    e.printStackTrace();
  715.  
    }
  716.  
    return null;
  717.  
    }
  718.  
  719.  
  720.  
    }
  721.  
 
 

3.SendEamil:用来发送邮箱(当上传失败时通过邮箱提醒)

代码如下:

 
  1.  
    package com.example.demo.apps;
  2.  
  3.  
    import com.sun.mail.util.MailSSLSocketFactory;
  4.  
    import org.springframework.beans.factory.annotation.Value;
  5.  
    import org.springframework.stereotype.Component;
  6.  
  7.  
    import javax.mail.*;
  8.  
    import javax.mail.internet.InternetAddress;
  9.  
    import javax.mail.internet.MimeMessage;
  10.  
    import java.security.GeneralSecurityException;
  11.  
    import java.util.Date;
  12.  
    import java.util.Properties;
  13.  
  14.  
    /* @date 日期:2023/5/6 时间:10:00
  15.  
    * @Description: 发送qq邮箱
  16.  
    * */
  17.  
    @Component
  18.  
    public class SendEamil {
  19.  
  20.  
    @Value("${Eamil.userName}")
  21.  
    String userName;
  22.  
  23.  
    @Value("${Eamil.passWord}")
  24.  
    String passWord;
  25.  
  26.  
    public void sendMail(String msg) throws Exception {
  27.  
    //创建一个配置文件并保存
  28.  
    Properties properties = new Properties();
  29.  
  30.  
    properties.setProperty("mail.host", "smtp.qq.com");
  31.  
  32.  
    properties.setProperty("mail.transport.protocol", "smtp");
  33.  
  34.  
    properties.setProperty("mail.smtp.auth", "true");
  35.  
  36.  
  37.  
    //QQ存在一个特性设置SSL加密
  38.  
    MailSSLSocketFactory sf = new MailSSLSocketFactory();
  39.  
    sf.setTrustAllHosts(true);
  40.  
    properties.put("mail.smtp.ssl.enable", "true");
  41.  
    properties.put("mail.smtp.ssl.socketFactory", sf);
  42.  
  43.  
    //创建一个session对象
  44.  
    Session session = Session.getDefaultInstance(properties, new Authenticator() {
  45.  
    @Override
  46.  
    protected PasswordAuthentication getPasswordAuthentication() {
  47.  
    return new PasswordAuthentication(userName, passWord);
  48.  
    }
  49.  
    });
  50.  
  51.  
    //开启debug模式
  52.  
    session.setDebug(true);
  53.  
  54.  
    //获取连接对象
  55.  
    Transport transport = session.getTransport();
  56.  
  57.  
    //连接服务器
  58.  
    transport.connect("smtp.qq.com", userName, passWord);
  59.  
  60.  
    //创建邮件对象
  61.  
    MimeMessage mimeMessage = new MimeMessage(session);
  62.  
  63.  
    //邮件发送人
  64.  
    mimeMessage.setFrom(new InternetAddress(userName));
  65.  
  66.  
    //邮件接收人
  67.  
    mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(userName));
  68.  
  69.  
    //邮件标题
  70.  
    mimeMessage.setSubject("BaiDuUpLoad");
  71.  
  72.  
    //邮件内容
  73.  
    Date date = new Date();
  74.  
  75.  
    mimeMessage.setContent(msg, "text/html;charset=UTF-8");
  76.  
  77.  
    //发送邮件
  78.  
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
  79.  
  80.  
    //关闭连接
  81.  
    transport.close();
  82.  
    }
  83.  
  84.  
    }
 
 

4.配置文件内容:

Constant:
  APP_ID: "32336141"
  APP_NAME: "HLS-BaiDu" #百度网盘中文件存放位置
  APP_KEY: "fBulUWK7sTZo2324gYSPveov9qsaq5LE"
  SECRET_KEY: "eapgT5k4XskRRgfxxlcxR82e3gursVze"
  refresh_token: "122.9faae9d9eaf4a0c9bfa41f4116fc7a45.Y37snJPhSu1H2J9oBJZ1qyLhLl6csbBVRiLZdhn.exqlBg"
  filePath: "e://test//" #文件压缩后的路径
  UNIT: 32
#上传失败发送地址
Eamil:
  userName: "2058461233@qq.com" #QQ邮箱
  passWord: "sfbqldhnxjakbicb" #授权码

logging:
  file:
    name: ./BaiDuUpload.log #日志文件存放位置

#定时任务
scheduling:
  executionTime: 0 0/1 * * * ?
  getAtoken: 0 0 2 1 * ? #每月1号凌晨2点执行一次

5.pom.xml配置

 
  1.  
    <dependency>
  2.  
    <groupId>org.springframework.boot</groupId>
  3.  
    <artifactId>spring-boot-starter</artifactId>
  4.  
    </dependency>
  5.  
  6.  
    <dependency>
  7.  
    <groupId>org.springframework.boot</groupId>
  8.  
    <artifactId>spring-boot-devtools</artifactId>
  9.  
    <scope>runtime</scope>
  10.  
    <optional>true</optional>
  11.  
    </dependency>
  12.  
    <dependency>
  13.  
    <groupId>org.projectlombok</groupId>
  14.  
    <artifactId>lombok</artifactId>
  15.  
    <optional>true</optional>
  16.  
    </dependency>
  17.  
    <dependency>
  18.  
    <groupId>org.springframework.boot</groupId>
  19.  
    <artifactId>spring-boot-starter-test</artifactId>
  20.  
    <scope>test</scope>
  21.  
    </dependency>
  22.  
    <dependency>
  23.  
    <groupId>org.apache.httpcomponents</groupId>
  24.  
    <artifactId>httpclient</artifactId>
  25.  
    <version>4.5</version>
  26.  
    </dependency>
  27.  
    <dependency>
  28.  
    <groupId>org.apache.httpcomponents</groupId>
  29.  
    <artifactId>httpmime</artifactId>
  30.  
    <version>4.5</version>
  31.  
    </dependency>
  32.  
    <dependency>
  33.  
    <groupId>cn.hutool</groupId>
  34.  
    <artifactId>hutool-all</artifactId>
  35.  
    <version>5.8.15</version>
  36.  
    </dependency>
  37.  
  38.  
    <dependency>
  39.  
    <groupId>org.apache.poi</groupId>
  40.  
    <artifactId>poi-ooxml</artifactId>
  41.  
    <version>5.1.0</version>
  42.  
    </dependency>
  43.  
  44.  
    <dependency>
  45.  
    <groupId>cn.hutool</groupId>
  46.  
    <artifactId>hutool-all</artifactId>
  47.  
    <version>5.8.16</version>
  48.  
    </dependency>
  49.  
  50.  
    <dependency>
  51.  
    <groupId>com.alibaba</groupId>
  52.  
    <artifactId>fastjson</artifactId>
  53.  
    <version>2.0.29</version>
  54.  
    </dependency>
  55.  
  56.  
    <dependency>
  57.  
    <groupId>org.jsoup</groupId>
  58.  
    <artifactId>jsoup</artifactId>
  59.  
    <version>1.16.1</version>
  60.  
    </dependency>
  61.  
  62.  
    <dependency>
  63.  
    <groupId>com.fasterxml.jackson.core</groupId>
  64.  
    <artifactId>jackson-databind</artifactId>
  65.  
    <version>2.15.0</version>
  66.  
    </dependency>
 
 

 

 
文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树首页概览117350 人正在系统学习中
posted @   苦行者的刀  阅读(609)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示