Baidu Netdisk Java バージョンはスライスでのファイルのアップロードをサポートしています

1. 認証と認可

2. リスト表示

3. ファイルクエリ

4. ファイルのプレビュー

5. ファイルのダウンロード

package net.aabg.dokisekai.utils.file;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.aabg.dokisekai.utils.file.baiducloud.bean.AllFIleInfo;

import net.aabg.dokisekai.utils.file.baiducloud.bean.FileInfo;

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.net.URLEncoder;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static net.aabg.dokisekai.utils.file.BDCD_Auth.APP_PATH;
import static net.aabg.dokisekai.utils.file.BDCD_Auth.getDeviceCode;

public class BaiduCloudDiskUtil {

    public static void main(String[] args) {
        upload();
    }

    /**
     * 获取设备码,用户码
     */
    public void getDevice() {

        getDeviceCode();
    }

    public static void upload() {

        String filePath = "/Users/snz/Documents/";
        String fileName = "AirServer.dmg";

        BDCD_Upload.upload(filePath, fileName);
    }

}


/**
 * 设备码授权模式
 */
class BDCD_Auth {

    /**
     * 应用名称
     */
    public static String APP_NAME = "javatest";

    /**
     * 应用路径
     */
    public static String APP_PATH = "/apps/" + APP_NAME + "/";//用于文件上传
    public static String APP_LOCAL_TO_PATH = "/Users/snz/Documents/tmp/";//用于文件上传
    /**
     * 应用账号
     */
    public static String APP_CLIENT_ID="";
    /**
     * 应用密钥
     */
    public static String APP_CLIENT_SECRET="";


    /**
     * 授权token
     */
    public static String APP_ACCESS_TOKEN = "token";
    /**
     * 刷新token
     */
    public static String APP_REFRESH_TOKEN;
    /**
     * 设备码
     */
    public static String DCODE;


    //单位mb
    // 普通用户单个分片大小固定为4MB(文件大小如果小于4MB,无需切片,直接上传即可),单文件总大小上限为4G。
    //普通会员用户单个分片大小上限为16MB,单文件总大小上限为10G。
    //超级会员用户单个分片大小上限为32MB,单文件总大小上限为20G。
    public static Integer UNIT = 32;

//    @Value("${baidu.cloud.disk.client_id}")
//    public String tmp_client_id = "";
//    @Value("${baidu.cloud.disk.client_secret}")
//    public String tmp_client_secret = "";

//用作spring配置文件获取
//    public void init() {
//        APP_CLIENT_ID = tmp_client_id;
//        APP_CLIENT_SECRET = tmp_client_secret;
//    }


    /**
     * @return 获取设备码、用户码
     */
    static JSONObject getDeviceCode() {
        JSONObject jsonObject = BDCD_HttpUtils.get(BDCD_Api.DEVICE_CODE_API);
        DCODE = jsonObject.get("device_code").toString();//获取设备码
        BDCD_Api.REFRESH_TOKEN_API = jsonObject.get("qrcode_url").toString();//授权码,扫码认证
        return jsonObject;
    }


    //3. 用 Device Code 轮询换取 Access Token
    private static JSONObject getAccessToken() {
        JSONObject jsonObject = BDCD_HttpUtils.get(BDCD_Api.TOKEN_API);
        APP_ACCESS_TOKEN = jsonObject.get("access_token").toString();
        APP_REFRESH_TOKEN = jsonObject.get("refresh_token").toString();
        return jsonObject;
    }


    /**
     * 刷新token
     */
    public static JSONObject refreshToken() {
        return BDCD_HttpUtils.get(BDCD_Api.REFRESH_TOKEN_API);
    }

    public static JSONObject userInfo() {
        return BDCD_HttpUtils.get(BDCD_Api.USER_INFO_API);
    }


    public static JSONObject diskSize() {
        return BDCD_HttpUtils.get(BDCD_Api.DISK_SIZE_API);
    }
}


class BDCD_UserInfo {
    public static String method = "uinfo";
    public static String access_token = BDCD_Auth.APP_ACCESS_TOKEN;

    public static void main(String[] args) {

        getUserInfo();
        getsize();
    }

    /*
     * 获取用户信息
     * */
    public static void getUserInfo() {
        try {
            URL url = new URL("https://pan.baidu.com/rest/2.0/xpan/nas?method=" + method + "&access_token=" + access_token);
            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(response.toString());
        } catch (Exception e) {
            System.out.println(e);
        }
    }


    /*
    获取网盘容量信息
    * checkfree	int	否	1	URL参数	是否检查免费信息,0为不查,1为查,默认为0
    * checkexpire	int	否	1	URL参数	是否检查过期信息,0为不查,1为查,默认为0
    * */
    public static void getsize() {
        try {
            URL url = new URL("https://pan.baidu.com/api/quota?" +
                    "access_token=" + access_token +
                    "&checkfree=1" +
                    "&checkexpire=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(response.toString());
        } catch (Exception e) {
            System.out.println(e);
        }
    }


}


class BDCD_HttpUtils {

    public static JSONObject get(String urlStr) {
        try {

            URL url = new URL(urlStr);
            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();

            return JSONObject.parseObject(response.toString());
        } catch (Exception e) {
            System.out.println(e);
        }
        return null;
    }

    /**
     * 构建完整get请求地址
     */
    public static String buidGetUrl(String urlStr, Map<String, Object> parm) {
        StringBuilder urlStrBuilder = new StringBuilder(urlStr);
        for (String s : parm.keySet()) {
            urlStrBuilder.append("&").append(s).append("=").append(parm.get(s));
        }
        urlStr = urlStrBuilder.toString();
        return urlStr;
    }

    /**
     * 构建完整get请求地址
     */
    public static String encode(String str) {
        try {
            return URLEncoder.encode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description: TODO 发送文件
     * @param: url 发送地址
     * @param: file 发送文件
     * @return: java.lang.String
     */
    public 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;
    }


    /**
     * 向指定 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;
    }


    /**
     * @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
     */
    public 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;
    }


}


class BDCD_FileInfo {

    //    获取路径下文件信息
    public static AllFIleInfo getFileList() {
        Map parmMap = new HashMap<>();//请求参数
        parmMap.put("access_token", BDCD_Auth.APP_ACCESS_TOKEN);//接口鉴权参数


        parmMap.put("dir", BDCD_HttpUtils.encode("/"));//需要list的目录,以/开头的绝对路径, 默认为/
        /*
        * 排序字段:默认为name;
            time表示先按文件类型排序,后按修改时间排序;
            name表示先按文件类型排序,后按文件名称排序;
            size表示先按文件类型排序,后按文件大小排序。
        * */
        parmMap.put("order", "name");
        //默认为升序,设置为1实现降序 (注:排序的对象是当前目录下所有文件,不是当前分页下的文件)
        parmMap.put("desc", 1);
        //起始位置,从0开始
        parmMap.put("start", 0);
        //查询数目,默认为1000,建议最大不超过1000
        parmMap.put("limit", 100);
        //值为1时,返回dir_empty属性和缩略图数据
        parmMap.put("web", 1);
        //        是否只返回文件夹,0 返回所有,1 只返回文件夹,且属性只返回path字段
        parmMap.put("folder", 0);
        //是否返回dir_empty属性,0 不返回,1 返回
        parmMap.put("showempty", 0);


        String url = BDCD_HttpUtils.buidGetUrl(BDCD_Api.FILE_INFO_API, parmMap);
        return JSONObject.parseObject(BDCD_HttpUtils.get(url).toString(), AllFIleInfo.class);

    }

    /**
     * @return
     */
    //    获取所有路径下文件信息
    public static AllFIleInfo getAllFileList(String path) {
        Map parmMap = new HashMap<>();//请求参数
        parmMap.put("access_token", BDCD_Auth.APP_ACCESS_TOKEN);//接口鉴权参数
        parmMap.put("path", BDCD_HttpUtils.encode("/交换区"));//需要list的目录,以/开头的绝对路径, 默认为/

        parmMap.put("recursion", 0);//是否递归,0为否,1为是,默认为0
        parmMap.put("order", "time");//排序字段:time(修改时间),name(文件名),size(大小,目录无大小),默认为文件类型
        parmMap.put("desc", 0);//0为升序,1为降序,默认为0
        parmMap.put("start", 0);//查询起点,默认为0
//        parmMap.put("limit", 1000);//查询数目,默认为1000; 如果设置start和limit参数,则建议最大设置为1000
//        parmMap.put("ctime", 1609430400);//文件上传时间,设置此参数,表示只返回上传时间大于ctime的文件
//        parmMap.put("mtime", 0);//文件修改时间,设置此参数,表示只返回修改时间大于mtime的文件
        parmMap.put("web", 0);//默认为0, 为1时返回缩略图地址

        String url = BDCD_HttpUtils.buidGetUrl(BDCD_Api.FILE_INFO_ALL_API, parmMap);
        return JSONObject.parseObject(BDCD_HttpUtils.get(url).toString(), AllFIleInfo.class);
    }

    /**
     * @param key 搜索文件名
     * @return
     */
    //搜素文件
    public static AllFIleInfo searchFile(String key) {

        Map parmMap = new HashMap<>();//请求参数
        parmMap.put("access_token", BDCD_Auth.APP_ACCESS_TOKEN);//接口鉴权参数
        parmMap.put("key", key);//搜索关键字
        parmMap.put("dir", BDCD_HttpUtils.encode("/交换区"));//搜索目录,默认根目录
        parmMap.put("page", 1);//页数,从1开始,缺省则返回所有条目
        parmMap.put("num", 100);//默认为500,不能修改
        parmMap.put("recursion", 1);//是否递归搜索子目录 1:是,0:否(默认)
        parmMap.put("web", 1);//默认0,为1时返回缩略图信息


        String url = BDCD_HttpUtils.buidGetUrl(BDCD_Api.SEARCH_FILE_API, parmMap);

        return JSONObject.parseObject(BDCD_HttpUtils.get(url).toString(), AllFIleInfo.class);
    }

    /**
     * @param fsids [414244021542671,633507813519281]
     * @return
     * @mark 查询文件详情
     */
    public static AllFIleInfo catFileInfo(String fsids) {
        fsids = "[" + fsids + "]";
        Map parmMap = new HashMap<>();//请求参数
        parmMap.put("access_token", BDCD_Auth.APP_ACCESS_TOKEN);//接口鉴权参数
        parmMap.put("fsids", fsids);//文件id数组,数组中元素是uint64类型,数组大小上限是:100
        parmMap.put("dlink", 1);//是否需要下载地址,0为否,1为是,默认为0。获取到dlink后,参考下载文档进行下载操作
        parmMap.put("path", BDCD_HttpUtils.encode("/"));//查询共享目录或专属空间内文件时需要。 共享目录格式: /uk-fsid  ;其中uk为共享目录创建者id, fsid对应共享目录的fsid ;专属空间格式:/_pcs_.appdata/xpan/
        parmMap.put("thumb", 1);//是否需要缩略图地址,0为否,1为是,默认为0
        parmMap.put("extra", 1);//图片是否需要拍摄时间、原图分辨率等其他信息,0 否、1 是,默认0
        parmMap.put("needmedia", 1);//视频是否需要展示时长信息,0 否、1 是,默认0

        String url = BDCD_HttpUtils.buidGetUrl(BDCD_Api.FILE_METAS_API, parmMap);
        AllFIleInfo fileInfo = JSONObject.parseObject(BDCD_HttpUtils.get(url).toString(), AllFIleInfo.class);
        return fileInfo;
    }


    /**
     * @param fsids
     * @return
     * @mark 构建多个文件信息获取
     */
    public static AllFIleInfo catFileInfo(Set<String> fsids) {
        StringBuilder fsidsStr = new StringBuilder();
        for (String fsid : fsids) {
            fsidsStr.append(fsid).append(",");
        }
        fsidsStr.substring(fsidsStr.length() - 1);
        return catFileInfo(fsidsStr.toString());
    }


}


class BDCD_Api {


    /*==================================================认证授权===========================================================*/
    /**
     * 获取设备码
     */
    public static String DEVICE_CODE_API = "https://openapi.baidu.com/oauth/2.0/device/code?response_type=device_code&scope=basic,netdisk&client_id="
            + BDCD_Auth.APP_CLIENT_ID;
    /**
     * 获取token-通过设备码
     */
    public static String TOKEN_API = "https://openapi.baidu.com/oauth/2.0/token?" +
            "grant_type=device_token" +
            "&code=" + BDCD_Auth.DCODE +
            "&client_id=" + BDCD_Auth.APP_CLIENT_ID +
            "&client_secret=" + BDCD_Auth.APP_CLIENT_SECRET;

    /**
     * 扫码认证路径
     */
    public static String AUTH_QRCODE_API;

    /**
     * 刷新token
     */
    public static String REFRESH_TOKEN_API = "https://openapi.baidu.com/oauth/2.0/token?" +
            "grant_type=refresh_token" +
            "&refresh_token=" + BDCD_Auth.APP_REFRESH_TOKEN +
            "&client_id=" + BDCD_Auth.APP_CLIENT_ID +
            "&client_secret=" + BDCD_Auth.APP_CLIENT_SECRET;

    /*==================================================用户信息===========================================================*/

    public static String USER_INFO_API = "https://pan.baidu.com/rest/2.0/xpan/nas?method=uinfo&access_token=" + BDCD_Auth.APP_ACCESS_TOKEN;
    public static String DISK_SIZE_API = "https://pan.baidu.com/api/quota?" +
            "access_token=" + BDCD_Auth.APP_ACCESS_TOKEN +
            "&checkfree=1" +
            "&checkexpire=1";


    /*==================================================文件信息===========================================================*/


    public static String FILE_INFO_API = "https://pan.baidu.com/rest/2.0/xpan/file?method=list";
    public static String FILE_INFO_ALL_API = "http://pan.baidu.com/rest/2.0/xpan/multimedia?method=listall";
    public static String SEARCH_FILE_API = "http://pan.baidu.com/rest/2.0/xpan/file?method=search";
    public static String FILE_METAS_API = "http://pan.baidu.com/rest/2.0/xpan/multimedia?method=filemetas";

    /*==================================================文件上传===========================================================*/
    //预上传
    public static String READY_UPLOAD_API = "https://pan.baidu.com/rest/2.0/xpan/file?method=precreate&access_token==" + BDCD_Auth.APP_ACCESS_TOKEN;
    /**
     * 文件上传
     */
    public static String UPLOAD_API = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?method=upload";

    /**
     * 文件创建
     */
    public static final String CREATE_FILE = "https://pan.baidu.com/rest/2.0/xpan/file?method=create&access_token=" + BDCD_Auth.APP_ACCESS_TOKEN;




    /*==================================================文件下载===========================================================*/
    /**
     * 文件下载
     */
    public static String DOWN_API = "https://d.pcs.baidu.com/file/1261d72d03471f7b7b805fd60e024b8d?" +
            "access_token=" + BDCD_Auth.APP_ACCESS_TOKEN;

}


@Slf4j
class BDCD_Upload {


    public static String URL_UPLOAD = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2";
    //预上传
    public static String URL_READY_URL_UPLOAD_FILE = "https://pan.baidu.com/rest/2.0/xpan/file";


    //    @SneakyThrows
    public static void upload(String filePath, String fileName) {

        File file = new File(filePath + fileName);//获取文件
        File[] files = new File[0];//
        try {
            files = split(filePath, fileName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        StringBuffer md5s = FileUtils.splitMd5(files);

        String cloudPath = APP_PATH + fileName;


        //预上传
        String precreate = precreate(cloudPath, file.length(), 0, md5s.toString());
        log.info("预上传{}", precreate);//获取uploadid


        String uploadid = (String) new cn.hutool.json.JSONObject(precreate).get("uploadid");
        //分片上传
        String upload = upload(cloudPath, uploadid, files);
        log.info("分片上传{}", upload);


        //创建文件
        String create = create(fileName, file.length(), 0, md5s.toString(), uploadid);
        log.info("创建文件{}", create);

        for (File file1 : files) {
            file1.delete();
        }


        String fid = JSON.parseObject(create, FileInfo.class).getFs_id();
        //获取下载地址
        String dlink = BDCD_FileInfo.catFileInfo(fid).getList().get(0).getDlink();
        System.out.println(dlink);
        log.info("文件下载地址", dlink);

    }

    //文件分片
    public static File[] split(String filePath, String fileName) throws Exception {
        String localFilePath = filePath + fileName;
        String to = "/Users/snz/Documents/tmp/";
        //文件分片并获取md5值
//        File[] separate = FileUtils.separate(localFilePath, BDCD_Auth.UNIT);//分片
        List<String> filesSet = FileSpiltAndMerge.spilt(localFilePath, BDCD_Auth.UNIT, to);//分片

        File[] files = new File[filesSet.size()];
        for (int i = 0; i < filesSet.size(); i++) {
            files[i] = new File(filesSet.get(i));
        }
        return files;
    }


    /**
     * @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 = URL_READY_URL_UPLOAD_FILE + "?method=precreate&access_token=" + BDCD_Auth.APP_ACCESS_TOKEN;
        String params = "path=" + cloudPath + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir;
        return BDCD_HttpUtils.open(strURL, params, "POST");
    }

    //文件预上传
    //文件上传
    //文件合并


    /**
     * @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 uploadid) {
        String strURL = "https://pan.baidu.com/rest/2.0/xpan/file" + "?method=create&access_token=" + BDCD_Auth.APP_ACCESS_TOKEN;
        String params = "path=" + APP_PATH + fileName + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir +
                "&uploadid=" + uploadid;
        return BDCD_HttpUtils.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 = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?method=upload" +
                        "&access_token=" + BDCD_Auth.APP_ACCESS_TOKEN +
                        "&type=tmpfile&partseq=" + i +
                        "&path=" + path +
                        "&uploadid=" + uploadid;
                String s = BDCD_HttpUtils.sendFile(url, files[i]);
                log.info("正在上传分片文件{}{}", s, i);
            }

            return path;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}


/*文件分片*/
class FileSpiltAndMerge {


    public static List<String> spilt(String from, int size, String to) throws Exception {

        List<String> files = new ArrayList<>();
        File f = new File(from);
        FileInputStream in = new FileInputStream(f);
        FileOutputStream out = null;
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = null;

        // 将MB单位转为为字节B
        long m = size * 1024 * 1024;
        // 计算最终会分成几个文件
        int count = (int) (f.length() / m);
        for (int i = 0; i <= count; i++) {
            // 生成文件的路径
            String t = to + "/AAA" + i;
            files.add(t);
            try {
                out = new FileOutputStream(new File(t));
                outChannel = out.getChannel();
                // 从inChannel的m*i处,读取固定长度的数据,写入outChannel
                if (i != count)
                    inChannel.transferTo(m * i, m, outChannel);
                else// 最后一个文件,大小不固定,所以需要重新计算长度
                    inChannel.transferTo(m * i, f.length() - m * count, outChannel);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                out.close();
                outChannel.close();
            }

        }
        in.close();
        inChannel.close();
        return files;
    }

    public static void merge(String from, String to) throws IOException {
        File t = new File(to);
        FileInputStream in = null;
        FileChannel inChannel = null;

        FileOutputStream out = new FileOutputStream(t, true);
        FileChannel outChannel = out.getChannel();

        File f = new File(from);
        // 获取目录下的每一个文件名,再将每个文件一次写入目标文件
        if (f.isDirectory()) {
            List<File> list = getAllFileAndSort(from);
            // 记录新文件最后一个数据的位置
            long start = 0;
            for (File file : list) {

                in = new FileInputStream(file);
                inChannel = in.getChannel();

                // 从inChannel中读取file.length()长度的数据,写入outChannel的start处
                outChannel.transferFrom(inChannel, start, file.length());
                start += file.length();
                in.close();
                inChannel.close();
            }
        }
        out.close();
        outChannel.close();
    }

    private static List<File> getAllFileAndSort(String dirPath) {
        File dirFile = new File(dirPath);
        File[] listFiles = dirFile.listFiles();
        List<File> list = Arrays.asList(listFiles);
        Collections.sort(list, (o1, o2) -> {
            return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName());
        });
        return list;
    }
}

おすすめ

転載: blog.csdn.net/weixin_44320239/article/details/130821837