欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot實(shí)現(xiàn)分段上傳功能的示例代碼

 更新時(shí)間:2022年07月26日 09:50:07   作者:木先生哦~  
這篇文章主要介紹了springboot實(shí)現(xiàn)分段上傳,包括文件上傳下載,斷點(diǎn)續(xù)傳,增量上傳功能,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

文件上傳下載

斷點(diǎn)續(xù)傳,增量上傳等

導(dǎo)入依賴

<!--jdk提供的關(guān)于文件上傳-->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.10.0</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<!--apache提供了的文件上傳-->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.14</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>

前端配置

前端使用的是webuploader

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webuploader</title>
</head>
<!--引入CSS-->
<link rel="stylesheet" type="text/css"  rel="external nofollow" >
<style>
    #upload-container, #upload-list{width: 500px; margin: 0 auto; }
    #upload-container{cursor: pointer; border-radius: 15px; background: #EEEFFF; height: 200px;}
    #upload-list{height: 800px; border: 1px solid #EEE; border-radius: 5px; margin-top: 10px; padding: 10px 20px;}
    #upload-container>span{widows: 100%; text-align: center; color: gray; display: block; padding-top: 15%;}
    .upload-item{margin-top: 5px; padding-bottom: 5px; border-bottom: 1px dashed gray;}
    .percentage{height: 5px; background: green;}
    .btn-delete, .btn-retry{cursor: pointer; color: gray;}
    .btn-delete:hover{color: orange;}
    .btn-retry:hover{color: green;}
</style>
<!--引入JS-->
<body>
    <div id="upload-container">
        <span>點(diǎn)擊或?qū)⑽募献е链松蟼?lt;/span>
    </div>
    <div id="upload-list">
        <!-- <div class="upload-item">
            <span>文件名:123</span>
            <span data-file_id="" class="btn-delete">刪除</span>
            <span data-file_id="" class="btn-retry">重試</span>
            <div class="percentage"></div>
        </div> -->
    </div>
    <button id="picker" style="display: none;">點(diǎn)擊上傳文件</button>
</body>
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
<script src="https://cdn.bootcss.com/webuploader/0.1.1/webuploader.js"></script>
<script>
    $('#upload-container').click(function(event) {
        $("#picker").find('input').click();
    });
    var uploader = WebUploader.create({
        auto: true,// 選完文件后,是否自動(dòng)上傳。
        swf: 'https://cdn.bootcss.com/webuploader/0.1.1/Uploader.swf',// swf文件路徑
        server: 'http://www.test.com/zyb.php',// 文件接收服務(wù)端。
        dnd: '#upload-container',
        pick: '#picker',// 內(nèi)部根據(jù)當(dāng)前運(yùn)行是創(chuàng)建,可能是input元素,也可能是flash. 這里是div的id
        multiple: true, // 選擇多個(gè)
        chunked: true,// 開起分片上傳。
        threads: 5, // 上傳并發(fā)數(shù)。允許同時(shí)最大上傳進(jìn)程數(shù)。
        method: 'POST', // 文件上傳方式,POST或者GET。
        fileSizeLimit: 1024*1024*100*100, //驗(yàn)證文件總大小是否超出限制, 超出則不允許加入隊(duì)列。
        fileSingleSizeLimit: 1024*1024*100, //驗(yàn)證單個(gè)文件大小是否超出限制, 超出則不允許加入隊(duì)列。
        fileVal:'upload', // [默認(rèn)值:'file'] 設(shè)置文件上傳域的name。
    });

    uploader.on('fileQueued', function(file) {
        // 選中文件時(shí)要做的事情,比如在頁面中顯示選中的文件并添加到文件列表,獲取文件的大小,文件類型等
        console.log(file.ext) // 獲取文件的后綴
        console.log(file.size) // 獲取文件的大小
        console.log(file.name);
        var html = '<div class="upload-item"><span>文件名:'+file.name+'</span><span data-file_id="'+file.id+'" class="btn-delete">刪除</span><span data-file_id="'+file.id+'" class="btn-retry">重試</span><div class="percentage '+file.id+'" style="width: 0%;"></div></div>';
        $('#upload-list').append(html);
    });

    uploader.on('uploadProgress', function(file, percentage) {
        console.log(percentage * 100 + '%');
        var width = $('.upload-item').width();
        $('.'+file.id).width(width*percentage);
    });

    uploader.on('uploadSuccess', function(file, response) {
        console.log(file.id+"傳輸成功");
    });

    uploader.on('uploadError', function(file) {
        console.log(file);
        console.log(file.id+'upload error')
    });

    $('#upload-list').on('click', '.upload-item .btn-delete', function() {
        // 從文件隊(duì)列中刪除某個(gè)文件id
        file_id = $(this).data('file_id');
        // uploader.removeFile(file_id); // 標(biāo)記文件狀態(tài)為已取消
        uploader.removeFile(file_id, true); // 從queue中刪除
        console.log(uploader.getFiles());
    });

    $('#upload-list').on('click', '.btn-retry', function() {
        uploader.retry($(this).data('file_id'));
    });

    uploader.on('uploadComplete', function(file) {
        console.log(uploader.getFiles());
    });
</script>
</html>

前端上傳數(shù)據(jù)

#前臺(tái)傳輸文件的表單信息
id: WU_FILE_1 文件ID
name: 錄制_2021_03_19_08_52_06_801.mp4 #文件名
type: video/mp4 #類型
lastModifiedDate: Fri Mar 19 2021 08:52:22 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)
size: 45711359 #大小
chunks: 9 #總分片數(shù)
chunk: 0  #當(dāng)前分片的編號(hào)
upload: (binary)

斷點(diǎn)續(xù)傳[增量上傳]

思路:前端會(huì)對文件進(jìn)行分片并以此調(diào)用此接口,后臺(tái)對文件進(jìn)行保存。當(dāng)判斷文件時(shí)最后一個(gè)分片文件的時(shí)候?qū)Ρ镜乇4娴奈募M(jìn)行組合。

@RequestMapping("/update")
public String update(HttpServletRequest request,MultipartFile files,
                     @RequestParam("chunks") Integer chunks,
                     @RequestParam("chunk") Integer chunk,
                     @RequestParam("name") String name){
    //根據(jù)原理,需要準(zhǔn)備寫的流os,寫的位置locate,
    //分片臨時(shí)位置tempLocate,當(dāng)前分片數(shù)chunk[表單獲取],總分片數(shù)chunks[表單獲取],
    //文件名稱name[表單獲取],臨時(shí)分片名稱tempName
    String tempName = null, locate="E:\\file",tempLocate="E:\\file\\temp";
    BufferedOutputStream os = null;
    try {
        //----------------參數(shù)判斷----------------
        if (name == null || chunk == null || chunks == null){
            log.error("參數(shù)未獲取到");
            return "";
        }
        if (files == null){
            log.error("數(shù)據(jù)上傳失敗");
            return "";
        }
        //----------------斷點(diǎn)續(xù)傳----------------
        tempName = name+"_"+chunk;
        File assest = new File(tempLocate,tempName);
        //文件不存在再寫,實(shí)現(xiàn)斷點(diǎn)續(xù)傳
        if (!assest.exists()){
            files.transferTo(assest);
        }
        //----------------合并數(shù)據(jù)----------------
        long curTime = System.currentTimeMillis();
        if (chunk == chunks-1){
            File file = new File(locate,name);
            os = new BufferedOutputStream(new FileOutputStream(file));

            for (int i = 0; i < chunks; i++) {
                File temp = new File(tempLocate,name+"_"+i);
                while (!temp.exists()){
                    //if (System.currentTimeMillis() - curTime > waitTime){
                    //    return "合并時(shí)過長,請重新上傳文件";
                    //}
                    Thread.sleep(100);
                }
                byte[] bytes = FileUtils.readFileToByteArray(temp);
                os.write(bytes);
                os.flush();
                temp.delete();
            }
            os.flush();
            return "上傳文件成功";
        }
    }catch (Exception e) {
        log.warn("文件上傳出錯(cuò)");
        return "文件上傳錯(cuò)誤,等待網(wǎng)頁維護(hù)人員進(jìn)行維護(hù)";
    } finally {
        try {
            if (os != null){
                os.close();
            }
        }catch (IOException e){
            log.info("文件上傳流關(guān)閉失敗");
        }
    }
    return "null";
}

分片下載

思路:前端支持分片,會(huì)在頭信息中帶有Range信息,內(nèi)容為起始位置-結(jié)束位置。通過range讀取文件傳給前端

須知:

  • 范圍讀取
  • 請求頭編寫

分片下載

@RequestMapping("/download")
public void download(HttpServletRequest request, HttpServletResponse response){
    File file = new File("E:\\file\\測試.mp4");
    if (!file.exists()){
        return;
    }

    //-----------------設(shè)置參數(shù)-----------------
    Long begin = 0l,//開始讀取位置
    fileSize=file.length(),//內(nèi)容長度
    end = fileSize - 1,//結(jié)束讀取位置
    curSize = 0l;//本次讀取分片的大小
    BufferedOutputStream os = null;//寫流
    RandomAccessFile is = null;//讀流
    String fileName;//文件名稱

    try {
        //-----------------設(shè)置文件的基礎(chǔ)參數(shù)-----------------
        //獲取文件名稱
        fileName = file.getName();
        String range = request.getHeader("Range");
        //判斷range:bytes=XXX-XXX
        if (range != null && range.contains("bytes=") && range.contains("-")){
            range = range.replaceAll("bytes=","").trim();
            String[] split = range.split("-");
            if (!StringUtils.hasLength(split[0])){
                //特殊情況1:-XXX
                end = Long.parseLong(split[1]);
            }else if (split.length == 1){
                //特殊情況2:XXX-
                begin = Long.parseLong(split[0]);
            }else if (split.length == 2){
                //理想情況
                begin = Long.parseLong(split[0]);
                end = Long.parseLong(split[1]);
                if (end > fileSize - 1){
                    end = fileSize - 1;
                }
            }
        }else {
            end = fileSize - 1;
        }
        curSize = end - begin + 1;
        //-----------------前端響應(yīng)頭設(shè)置-----------------
        //設(shè)置為下載
        response.setContentType("application/x-download");
        //設(shè)置下載文件的信息
        response.addHeader("Content-Disposition",
                           "attachment;filename="+new String(fileName.getBytes(),"ISO8859_1"));
        //支持分片下載
        response.setHeader("Accept-Ranges","bytes");
        //Content-Type 表示資源類型,如:文件類型
        response.setHeader("Content-Type", request.getServletContext().getMimeType(fileName));
        //設(shè)置文件大小
        response.setHeader("Content-Length",String.valueOf(curSize));
        //設(shè)置響應(yīng)數(shù)據(jù)量:bytes [下載開始位置]-[結(jié)束位置]/[文件大小]
        response.setHeader("Content-Range","bytes "+begin+"-"+end+"/"+fileSize);
        //設(shè)置專門的響應(yīng)類型
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        //自定義一些文件頭
        response.setHeader("fileSize", String.valueOf(fileSize));
        response.setHeader("fileName", new String(fileName.getBytes(),"ISO8859_1"));

        //-----------------讀寫文件-----------------
        os = new BufferedOutputStream(response.getOutputStream());
        is = new RandomAccessFile(file,"r");
        byte[] buffer = new byte[1024];
        int len = 0;
        Long sum = 0l;//累計(jì)添加的流
        //跳過已經(jīng)獲取的
        is.seek(begin);
        while (sum<curSize){
            int readSize = buffer.length;
            if ((curSize-sum)<readSize){
                readSize = (int) (curSize-sum);
            }
            if ((len = is.read(buffer,0,readSize))==-1){
                break;
            }
            os.write(buffer,0,len);
            sum+=len;
        }
        log.info("下載成功");
    } catch (Exception e) {
        log.warn("下載出現(xiàn)錯(cuò)誤");
    }finally {
        if (os != null){
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (is != null){
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

分片下載合并

前端不好對文件進(jìn)行分片的合并,需要后端進(jìn)行合并處理

思路:

  • 通過JAVA模擬請求
  • 將文件通過 FileUtils.readFileToByteArray(temp);讀取合并

不進(jìn)行延伸的原因:

  • 對于B/S結(jié)構(gòu),因?yàn)闊o法知道用戶下載文件的具體位置,就無法進(jìn)行合并
  • 為了用戶安全,每個(gè)分片下載都會(huì)進(jìn)行提示,用戶體驗(yàn)差

綜合所述,除了C/S結(jié)構(gòu),本地端不建議使用

到此這篇關(guān)于springboot實(shí)現(xiàn)分段上傳的文章就介紹到這了,更多相關(guān)springboot分段上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • jasypt dubbo配置密文存放使用詳解

    jasypt dubbo配置密文存放使用詳解

    這篇文章主要介紹了jasypt dubbo配置密文存放使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Servlet第一個(gè)項(xiàng)目的發(fā)布(入門)

    Servlet第一個(gè)項(xiàng)目的發(fā)布(入門)

    這篇文章主要介紹了Servlet第一個(gè)項(xiàng)目的發(fā)布,下面是用servlet實(shí)現(xiàn)的一個(gè)簡單的web項(xiàng)目,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-04-04
  • 工廠模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    工廠模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了工廠模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理的相關(guān)資料,需要的朋友可以參考下
    2017-08-08
  • 解決nacos升級(jí)spring cloud 2020.0無法使用bootstrap.yml的問題

    解決nacos升級(jí)spring cloud 2020.0無法使用bootstrap.yml的問題

    這篇文章主要介紹了解決nacos升級(jí)spring cloud 2020.0無法使用bootstrap.yml的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java生成隨機(jī)字符串的兩種方法

    java生成隨機(jī)字符串的兩種方法

    這篇文章主要為大家詳細(xì)介紹了java生成隨機(jī)字符串的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 基于SpringBoot?Mock單元測試詳解

    基于SpringBoot?Mock單元測試詳解

    這篇文章主要介紹了基于SpringBoot?Mock單元測試詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java高并發(fā)ScheduledThreadPoolExecutor類深度解析

    java高并發(fā)ScheduledThreadPoolExecutor類深度解析

    這篇文章主要為大家介紹了java高并發(fā)ScheduledThreadPoolExecutor類源碼深度解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 使用Java如何將圖片轉(zhuǎn)成Base64編碼,并壓縮至40k

    使用Java如何將圖片轉(zhuǎn)成Base64編碼,并壓縮至40k

    這篇文章主要介紹了使用Java如何將圖片轉(zhuǎn)成Base64編碼,并壓縮至40k問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • java 獲取mac地址的兩種方法(推薦)

    java 獲取mac地址的兩種方法(推薦)

    下面小編就為大家?guī)硪黄猨ava 獲取mac地址的兩種方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-10-10
  • Spring-Boot中如何使用多線程處理任務(wù)方法

    Spring-Boot中如何使用多線程處理任務(wù)方法

    這篇文章主要介紹了Spring-Boot中如何使用多線程處理任務(wù)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01

最新評論