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

Java斷點(diǎn)續(xù)傳(文件分塊)完整實(shí)現(xiàn)步驟

 更新時(shí)間:2025年05月22日 10:14:25   作者:破曉*  
這篇文章主要介紹了Java斷點(diǎn)續(xù)傳(文件分塊)完整實(shí)現(xiàn)步驟,?斷點(diǎn)續(xù)傳通過(guò)分塊傳輸大文件,中斷后可續(xù)傳未完成部分,服務(wù)端合并分塊,避免重復(fù)上傳,提升用戶體驗(yàn)并節(jié)省網(wǎng)絡(luò)資源,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

什么是斷點(diǎn)續(xù)傳?

引用百度百科:對(duì)斷點(diǎn)續(xù)傳的定義

個(gè)人理解:如果我們要在項(xiàng)目的媒資管理部分,上傳視頻文件(通常這類視頻文件都比較大),http協(xié)議本身對(duì)上傳文件大小沒(méi)有限制,但是客戶的網(wǎng)絡(luò)環(huán)境質(zhì)量,電腦硬件環(huán)境參差不齊,可能會(huì)導(dǎo)致一個(gè)大文件快上傳完了出現(xiàn)斷網(wǎng)的情況,從而導(dǎo)致文件沒(méi)有上傳成功,需要客戶重新上傳,用戶體驗(yàn)非常差,所以對(duì)于大文件上傳的要求是能做到 斷點(diǎn)續(xù)傳

斷點(diǎn)續(xù)傳流程圖如下圖:

簡(jiǎn)要概述實(shí)現(xiàn)步驟:

  • 前端上傳完先把文件分成塊
  • 一塊一塊的上傳,上傳中斷后重新上傳,已上傳的分塊則不用再上傳
  • 各分塊上傳完成最后在服務(wù)端合并文件

(為了方便理解,我用Java代碼的方法 測(cè)試文件的分塊與合并)

先進(jìn)行大文件資源 分塊操作:

1.導(dǎo)入一系列的包

package com.xuecheng.media;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.*;

導(dǎo)入多個(gè)外部和Java自帶的庫(kù),其中org.apache.commons.codec.digest.DigestUtils:用于生成文章的摘要,能夠在斷點(diǎn)續(xù)傳中驗(yàn)證文件的完整性

2.定義相關(guān)的類和方法

public class BigFileTest {
    //測(cè)試文件分塊方法
    @Test
    public void testChunk() throws IOException {

定義一個(gè)公共類BigFileTest,用于包含文件處理相關(guān)的測(cè)試方法,并且定義了一個(gè)testChunk方法,該方法用于執(zhí)行文件分塊操作,并聲明了可能拋出IOException異常,因?yàn)槲募僮骺赡軙?huì)失敗

3.創(chuàng)建分塊文件

File sourceFile = new File("d:/develop/bigfile_test/nacos.mp4");
String chunkPath = "d:/develop/bigfile_test/chunk/";
File chunkFolder = new File(chunkPath);
if (!chunkFolder.exists()) {
    chunkFolder.mkdirs();
}

創(chuàng)建一個(gè)File對(duì)象,表示要對(duì)d:/develop/bigfile_test/路徑下的nacos.mp4源文件進(jìn)行分塊,并創(chuàng)建一個(gè)File對(duì)象,表示分塊存儲(chǔ)的文件夾,如果分塊文件夾不存在,則創(chuàng)建它

 4.對(duì)大文件分成文件塊

//分塊大小
long chunkSize = 1024 * 1024 * 1;
//分塊數(shù)量
long chunkNum = (long) Math.ceil(sourceFile.length() * 1.0 / chunkSize);
System.out.println("分塊總數(shù):" + chunkNum);

然后對(duì) 文件進(jìn)行分割,定義每個(gè)分塊的大小,通過(guò)源文件的長(zhǎng)度除以分塊大小(要采用向上取整噢)使用Math.ceil方法向上取整,計(jì)算出分塊的總數(shù)

5.進(jìn)行對(duì)文件的讀取寫入

//緩沖區(qū)大小
byte[] b = new byte[1024];
//使用RandomAccessFile訪問(wèn)文件
RandomAccessFile raf_read = new RandomAccessFile(sourceFile, "r");
//分塊
for (int i = 0; i < chunkNum; i++) {
    //創(chuàng)建分塊文件
    File file = new File(chunkPath + i);
    if (file.exists()) {
        file.delete();
    }
    boolean newFile = file.createNewFile();
    if (newFile) {
        //向分塊文件中寫數(shù)據(jù)
        RandomAccessFile raf_write = new RandomAccessFile(file, "rw");
        int len = -1;
        while ((len = raf_read.read(b))!= -1) {
            raf_write.write(b, 0, len);
            if (file.length() >= chunkSize) {
                break;
            }
        }
        raf_write.close();
        System.out.println("完成分塊" + i);
    }
}
raf_read.close();

然后進(jìn)行緩沖區(qū)與文件讀取寫入,以上代碼塊創(chuàng)建了一個(gè)大小為1024字節(jié)的緩沖區(qū)數(shù)組b,用于讀取源文件數(shù)據(jù),并且以只讀模式打開(kāi)源文件,然后進(jìn)行分塊操作

循環(huán)分塊數(shù)量chunkNum(對(duì)源文件進(jìn)行分塊后得到的分塊總數(shù)),if循環(huán)判斷分塊文件是否創(chuàng)建成功,如果創(chuàng)建成功,則從源文件中讀取數(shù)據(jù)到緩沖區(qū),直到讀取到文件末尾

再進(jìn)行分塊文件 合并操作:

各個(gè)文件塊讀取完畢后,就可以進(jìn)行 文件合并 操作,分塊合并步驟

File chunkFolder = new File("D:\\...\\chunk\\");  // 分塊文件目錄
File sourceFile = new File("D:\\...\\星際牛仔1.mp4");  // 原始文件
File mergeFile = new File("D:\\...\\星際牛仔1-1.mp4");  // 合并后的文件
mergeFile.createNewFile();  // 創(chuàng)建空的目標(biāo)文件

定義分塊文件的存儲(chǔ)目錄,原始文件路徑和合并后的文件路徑,并創(chuàng)建一個(gè)空的目標(biāo)文件

RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");  // 以讀寫模式打開(kāi)合并文件
byte[] buffer = new byte[1024];  // 讀寫緩沖區(qū)(1KB)

初始化寫入流,RandomAccessFile是一個(gè)用于隨機(jī)訪問(wèn)文件的類,適合大文件操作,“rw”表示讀寫模式,byte[ ] buffer = new byte[1024]這段代碼創(chuàng)建了一個(gè)字節(jié)數(shù)組,作為讀寫緩沖區(qū)(臨時(shí)存儲(chǔ)從文件或網(wǎng)絡(luò)中讀取的數(shù)據(jù)),每次讀取1KB數(shù)據(jù),減少磁盤I/O次數(shù)

//listFiles()表示返回目錄中所有文件和子目錄的File數(shù)組,files是包含所有分塊文件的數(shù)組
File[] files = chunkFolder.listFiles();
//將數(shù)組轉(zhuǎn)換為list集合,fileList是包含所以分塊文件的list<File>
List<File> fileList = Arrays.asList(files);
//然后對(duì)List進(jìn)行排序,Comparator.comparingInt創(chuàng)建一個(gè)比較器,按照指定規(guī)則排序(將文件名轉(zhuǎn)換為整數(shù)進(jìn)行排序)
Collections.sort(fileList, Comparator.comparingInt(o -> Integer.parseInt(o.getName())));

對(duì)分塊文件進(jìn)行排序,o -> Integer.parseInt(o.getName()):是一個(gè)Lambda表達(dá)式,用于將文件名轉(zhuǎn)換為整數(shù)進(jìn)行排序

//循環(huán)遍歷分塊文件列表
for (File chunkFile : fileList) {
//以只讀模式打開(kāi)分塊文件 "r"表示以只讀模式打開(kāi)
    RandomAccessFile raf_read = new RandomAccessFile(chunkFile, "r"); 
//讀取分塊文件內(nèi)容并寫入合并文件
    int len;
    while ((len = raf_read.read(buffer)) != -1) {  
        raf_write.write(buffer, 0, len);  
    }
    raf_read.close();  // 關(guān)閉分塊文件流
}
raf_write.close();  // 關(guān)閉合并文件流

這段代碼遍歷分塊文件列表,并以只讀模式打開(kāi)分塊文件,然后讀取分塊文件內(nèi)容并寫入到合并文件,最后關(guān)閉分塊文件流和合并文件流

這里我再總結(jié)一下掌握斷點(diǎn)續(xù)傳的技術(shù),我們能夠?qū)⒍鄠€(gè)分塊文件合并成一個(gè)完整文件,避免用戶在下載過(guò)程因?yàn)榫W(wǎng)絡(luò),系統(tǒng)等一系列原因?qū)е孪螺d中斷,而需重新開(kāi)始下載的情況。而是可以直接從中斷處繼續(xù)下載,節(jié)省了我們時(shí)間和網(wǎng)絡(luò)資源

總結(jié) 

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

相關(guān)文章

  • SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例

    SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例

    本文主要介紹了SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 利用Java實(shí)現(xiàn)調(diào)用http請(qǐng)求

    利用Java實(shí)現(xiàn)調(diào)用http請(qǐng)求

    在實(shí)際開(kāi)發(fā)過(guò)程中,我們經(jīng)常需要調(diào)用對(duì)方提供的接口或測(cè)試自己寫的接口是否合適。本文就為大家準(zhǔn)備了幾個(gè)java調(diào)用http請(qǐng)求的幾種常見(jiàn)方式,需要的可以參考一下
    2022-08-08
  • maven項(xiàng)目無(wú)法讀取到resource文件夾的問(wèn)題

    maven項(xiàng)目無(wú)法讀取到resource文件夾的問(wèn)題

    這篇文章主要介紹了maven項(xiàng)目無(wú)法讀取到resource文件夾的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 使用mybatis的interceptor修改執(zhí)行sql以及傳入?yún)?shù)方式

    使用mybatis的interceptor修改執(zhí)行sql以及傳入?yún)?shù)方式

    這篇文章主要介紹了使用mybatis的interceptor修改執(zhí)行sql以及傳入?yún)?shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Springboot中實(shí)現(xiàn)接口冪等性的4種方案小結(jié)

    Springboot中實(shí)現(xiàn)接口冪等性的4種方案小結(jié)

    本文主要介紹了Springboot中實(shí)現(xiàn)接口冪等性,包含數(shù)據(jù)庫(kù)的冪等,數(shù)據(jù)庫(kù)的冪等,Redis的冪等性和Token + 時(shí)間戳的冪等性,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解

    SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解

    這篇文章主要介紹了SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解,需要的朋友可以參考下
    2017-09-09
  • Java中super和this關(guān)鍵字詳解

    Java中super和this關(guān)鍵字詳解

    這篇文章主要介紹了Java中super和this關(guān)鍵字詳解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-06-06
  • 可視化定時(shí)任務(wù)quartz集成解析全過(guò)程

    可視化定時(shí)任務(wù)quartz集成解析全過(guò)程

    在開(kāi)發(fā)中有很多定時(shí)任務(wù)都不是寫死的而是可以人為配置并且寫到數(shù)據(jù)庫(kù)中的,下面這篇文章主要給大家介紹了關(guān)于可視化定時(shí)任務(wù)quartz集成解析的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • Java中map遍歷方式的選擇問(wèn)題詳解

    Java中map遍歷方式的選擇問(wèn)題詳解

    這篇文章主要介紹了Java中map遍歷方式的選擇問(wèn)題的相關(guān)內(nèi)容,小編覺(jué)得挺不錯(cuò)的,在則里分享給大家,需要的朋友可以參考下。
    2017-10-10
  • 解決異常FileNotFoundException:class path resource找不到資源文件的問(wèn)題

    解決異常FileNotFoundException:class path resource找不到資源文件的問(wèn)題

    今天小編就為大家分享一篇關(guān)于解決異常FileNotFoundException:class path resource找不到資源文件的問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12

最新評(píng)論