最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java視頻斷點上傳的實現(xiàn)示例

 更新時間:2024年05月08日 09:11:16   作者:拉普蘭德做的到嗎?  
斷點續(xù)傳指的是在下載或上傳時,將下載或上傳任務(wù)人為的劃分為幾個部分,本文主要介紹了Java視頻斷點上傳的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下

什么是斷點續(xù)傳

通常視頻文件都比較大,所以對于媒資系統(tǒng)上傳文件的需求要滿足大文件的上傳要求。http協(xié)議本身對上傳文件大小沒有限制,但是客戶的網(wǎng)絡(luò)環(huán)境質(zhì)量、電腦硬件環(huán)境等參差不齊,如果一個大文件快上傳完了網(wǎng)斷了沒有上傳完成,需要客戶重新上傳,用戶體驗非常差,所以對于大文件上傳的要求最基本的是斷點續(xù)傳。

什么是斷點續(xù)傳:

引用百度百科:斷點續(xù)傳指的是在下載或上傳時,將下載或上傳任務(wù)(一個文件或一個壓縮包)人為的劃分為幾個部分,每一個部分采用一個線程進行上傳或下載,如果碰到網(wǎng)絡(luò)故障,可以從已經(jīng)上傳或下載的部分開始繼續(xù)上傳下載未完成的部分,而沒有必要從頭開始上傳下載,斷點續(xù)傳可以提高節(jié)省操作時間,提高用戶體驗性。

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

流程如下:

1、前端上傳前先把文件分成塊

2、一塊一塊的上傳,上傳中斷后重新上傳,已上傳的分塊則不用再上傳

3、各分塊上傳完成最后在服務(wù)端合并文件

 文件分塊

文件分塊的流程如下:

1、獲取源文件長度

2、根據(jù)設(shè)定的分塊文件的大小計算出塊數(shù)

3、從源文件讀數(shù)據(jù)依次向每一個塊文件寫數(shù)據(jù)。

/**
     * 文件分塊上傳測試
     */
    @Test
    public  void  testChunk(){
        //獲取源文件
        File sourceFile = new File("B:\\workspace\\test\\you.ncm");
        //源文件字節(jié)大小
        long length = sourceFile.length();
        //分塊文件目錄
        String chunkPath="B:\\workspace\\test\\chunk\\";
        File chunkFolder = new File(chunkPath);
        //檢查目錄是否存在
        if (!chunkFolder.exists()) {
            //不存在就創(chuàng)建
            chunkFolder.mkdirs();
        }
        //分塊大小
        long chunkSize = 1024*1024*1;
        //分塊數(shù)量
        long chunkNum = (long) Math.ceil(length * 1.0 / chunkSize);
        //緩沖區(qū)大小
        byte[] b = new byte[1024];
        //使用RandomAccessFile訪問文件
        try {
            RandomAccessFile 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();
                }
                //創(chuàng)建一個新文件
                boolean newFile = file.createNewFile();
                if (newFile){
                    //向分塊文件中寫數(shù)據(jù)
                    RandomAccessFile write = new RandomAccessFile(file,"rw");
                    int len = -1;
                    while ((len = read.read(b)) != -1) {
                        write.write(b, 0, len);
                        //如果分塊文件的大小大于等于分塊大小就跳過本次循環(huán)
                        if (file.length() >= chunkSize) {
                            break;
                        }
                    }
                    write.close();
                    System.out.println("完成分塊"+i);
                }

            }
            read.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

RandomAccessFile 是 Java 中的一個類,它允許對文件的任意位置進行讀寫操作。與其他的輸入/輸出流(如 InputStream 和 OutputStream)不同,RandomAccessFile 并不屬于它們的類系,而是直接繼承自 Object 類。它提供了類似于文件系統(tǒng)中的隨機訪問功能,因此得名“隨機訪問文件”。

以下是 RandomAccessFile 的一些主要特點和功能:

  • 隨機訪問RandomAccessFile 允許你直接跳到文件的任意位置來讀寫數(shù)據(jù)。這是通過使用 seek(long pos) 方法實現(xiàn)的,它可以將文件的指針移動到指定的位置。
  • 讀寫功能RandomAccessFile 既可以從文件中讀取數(shù)據(jù),也可以向文件中寫入數(shù)據(jù)。它提供了類似于 InputStream 的 read() 方法和類似于 OutputStream 的 write() 方法來執(zhí)行這些操作。
  • 文件指針操作:除了 seek(long pos) 方法外,RandomAccessFile 還提供了 getFilePointer() 方法來返回文件記錄指針的當前位置。
  • 訪問模式:在創(chuàng)建 RandomAccessFile 對象時,你需要指定一個訪問模式,它決定了文件是以只讀方式打開還是以讀寫方式打開。常見的訪問模式有 "r"(只讀)和 "rw"(讀寫)。
  • 文件操作模式:在 JDK 1.6 及更高版本中,RandomAccessFile 還支持 "rws" 和 "rwd" 模式。在 "rws" 模式下,每次寫入操作都會確保數(shù)據(jù)被寫入到磁盤中;而在 "rwd" 模式下,只有在對文件執(zhí)行了某些特定的更新操作(如關(guān)閉文件或調(diào)用 flush() 方法)后,數(shù)據(jù)才會被寫入到磁盤中。
  • 內(nèi)存映射文件:雖然 RandomAccessFile 提供了強大的文件訪問功能,但在某些情況下,使用 JDK 1.4 引入的“內(nèi)存映射文件”可能會更高效。內(nèi)存映射文件允許你將文件的一部分或全部映射到內(nèi)存中,從而可以像訪問內(nèi)存一樣快速地訪問文件。

文件合并 

文件合并流程:

1、找到要合并的文件并按文件合并的先后進行排序。

2、創(chuàng)建合并文件

3、依次從合并的文件中讀取數(shù)據(jù)向合并文件寫入數(shù)

文件合并的測試代碼 :

//測試文件合并方法
    @Test
    public void testMerge(){
        try {
            //獲取源文件
            File sourceFile = new File("B:\\workspace\\test\\you.ncm");
            //分塊文件目錄
            String chunkPath="B:\\workspace\\test\\chunk\\";
            //合并后的文件
            File mergeFile = new File("B:\\workspace\\test\\you1.ncm");
            if (mergeFile.exists()) {
                mergeFile.delete();
            }
            //創(chuàng)建新的合并文件
            mergeFile.createNewFile();
            RandomAccessFile write = new RandomAccessFile(mergeFile,"rw");
            //指針指向文件頂端
            write.seek(0);
            //緩沖區(qū)
            byte[] b = new byte[1024];
            //獲取分塊文件數(shù)組
            File file = new File(chunkPath);
            File[] files = file.listFiles();
            // 轉(zhuǎn)成集合,便于排序
            List<File> fileList = Arrays.asList(files);
            //使用工具類和自定義比較類進行排序

            Collections.sort(fileList, new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    Integer o1Name = Integer.parseInt(o1.getName());
                    Integer o2Name=Integer.parseInt(o2.getName());
                    return o1Name-o2Name;
                }
            });
            //合并文件
            for (File file1 : fileList) {
                RandomAccessFile read = new RandomAccessFile(file1,"r");
                int len = -1;
                while ((len = read.read(b)) != -1) {
                    write.write(b, 0, len);

                }
                read.close();
            }
            write.close();
            //校驗文件
            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            FileInputStream mergeFileStream = new FileInputStream(mergeFile);
            //取出原始文件的md5
            String originalMd5 = DigestUtils.md5Hex(fileInputStream);
            //取出合并文件的md5進行比較
            String mergeFileMd5 = DigestUtils.md5Hex(mergeFileStream);
            if (originalMd5.equals(mergeFileMd5)) {
                System.out.println("合并文件成功");
            } else {
                System.out.println("合并文件失敗");
            }





        } catch (Exception e) {
            e.printStackTrace();
        }


    }

視頻上傳流程 

1、前端對文件進行分塊。

2、前端上傳分塊文件前請求媒資服務(wù)檢查文件是否存在,如果已經(jīng)存在則不再上傳。

3、如果分塊文件不存在則前端開始上傳

4、前端請求媒資服務(wù)上傳分塊。

5、媒資服務(wù)將分塊上傳至MinIO。

6、前端將分塊上傳完畢請求媒資服務(wù)合并分塊。

7、媒資服務(wù)判斷分塊上傳完成則請求MinIO合并文件。

8、合并完成校驗合并后的文件是否完整,如果不完整則刪除文件。

測試將分塊文件上傳至minio

 //將分塊文件上傳至minio
    @Test
    public void uploadChunk(){
        String chunkFolderPath = "B:\\workspace\\test\\chunk\\";
        File chunkFolder = new File(chunkFolderPath);
        //分塊文件
        File[] files = chunkFolder.listFiles();
        //將分塊文件上傳至minio
        for (int i = 0; i < files.length; i++) {
            try {
                UploadObjectArgs uploadObjectArgs = UploadObjectArgs
                                                      .builder()
                                                      .bucket("testbucket")//桶名
                                                      .object("chunk/" + i)//存儲路徑+文件名
                                                      .filename(files[i].getAbsolutePath())
                                                      .build();
                minioClient.uploadObject(uploadObjectArgs);
                System.out.println("上傳分塊成功"+i);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

測試通過minio的合并文件

//合并文件,要求分塊文件最小5M
    @Test
    public void test_merge() throws Exception {
        List<ComposeSource> sources = new ArrayList<>();
        for (int i = 0; i <=7; i++) {
            ComposeSource composeSource = ComposeSource
                    .builder()//指定分塊文件信息
                    .bucket("testbucket")
                    .object("chunk/" + (Integer.toString(i)))//目標文件信息
                    .build();
            sources.add(composeSource);
        }
        ComposeObjectArgs composeObjectArgs = ComposeObjectArgs
                                                        .builder()
                                                        .bucket("testbucket")
                                                        .object("merge01.npm")//目標文件
                                                        .sources(sources)//源文件
                                                        .build();
        //合并文件
        minioClient.composeObject(composeObjectArgs);

    }

測試minio清除分塊文件 

//清除分塊文件
    @Test
    public void test_removeObjects(){
        //合并分塊完成將分塊文件清除
        List<DeleteObject> deleteObjects = Stream.iterate(0, i -> ++i)
                .limit(2)//循環(huán)幾次
                .map(i -> new DeleteObject("chunk/".concat(Integer.toString(i))))
                .collect(Collectors.toList());

        RemoveObjectsArgs removeObjectsArgs = RemoveObjectsArgs.builder().bucket("testbucket").objects(deleteObjects).build();
        Iterable<Result<DeleteError>> results = minioClient.removeObjects(removeObjectsArgs);
        results.forEach(r->{
            DeleteError deleteError = null;
            try {
                deleteError = r.get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

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

相關(guān)文章

  • Java中的傳值與傳引用實現(xiàn)過程解析

    Java中的傳值與傳引用實現(xiàn)過程解析

    這篇文章主要介紹了java中的傳值與傳引用實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot實現(xiàn)數(shù)據(jù)轉(zhuǎn)換的四種對象映射方案

    SpringBoot實現(xiàn)數(shù)據(jù)轉(zhuǎn)換的四種對象映射方案

    在項目開發(fā)中,對象之間的相互轉(zhuǎn)換是一個高頻操作,尤其在分層架構(gòu)的系統(tǒng)中,數(shù)據(jù)在實體對象(Entity)、數(shù)據(jù)傳輸對象(DTO)、值對象(VO)之間的轉(zhuǎn)換尤為常見,選擇一個高效、可靠的對象映射方案對提高系統(tǒng)性能和開發(fā)效率至關(guān)重要,本文將介紹4種對象映射方案
    2025-06-06
  • java8根據(jù)某一屬性過濾去重的實例

    java8根據(jù)某一屬性過濾去重的實例

    這篇文章主要介紹了java8根據(jù)某一屬性過濾去重的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Spring?Boot整合持久層之JdbcTemplate多數(shù)據(jù)源

    Spring?Boot整合持久層之JdbcTemplate多數(shù)據(jù)源

    持久層是JavaEE中訪問數(shù)據(jù)庫的核心操作,SpringBoot中對常見的持久層框架都提供了自動化配置,例如JdbcTemplate、JPA 等,MyBatis 的自動化配置則是MyBatis官方提供的。接下來分別向讀者介紹Spring Boot整合這持久層技術(shù)中的整合JdbcTemplate
    2022-08-08
  • hibernate通過session實現(xiàn)增刪改查操作實例解析

    hibernate通過session實現(xiàn)增刪改查操作實例解析

    這篇文章主要介紹了hibernate通過session實現(xiàn)增刪改查操作實例解析,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • java 中堆內(nèi)存和棧內(nèi)存理解

    java 中堆內(nèi)存和棧內(nèi)存理解

    這篇文章主要介紹了java 中的堆內(nèi)存和棧內(nèi)存的知識,有需要的朋友可以參考下
    2017-03-03
  • idea拉取代碼的時候需要輸入token的問題分析及解決過程

    idea拉取代碼的時候需要輸入token的問題分析及解決過程

    文章介紹了如何在WebStorm中配置GitLab并生成Token,以簡化后續(xù)的Git操作,同時,文章建議禁用或刪除GitLab插件以進一步提高效率
    2026-01-01
  • Java中讓界面內(nèi)的時間及時更新示例代碼

    Java中讓界面內(nèi)的時間及時更新示例代碼

    這篇文章主要給大家介紹了關(guān)于Java中讓界面內(nèi)的時間及時更新的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Spring?Batch是什么

    Spring?Batch是什么

    SpringBatch是Spring框架的批量處理工具,支持大規(guī)模數(shù)據(jù)任務(wù)、錯誤處理及監(jiān)控,在SpringBoot中通過Starter簡化集成,結(jié)合分頁、Swagger、ActiveMQ等技術(shù),具備高性能和健壯性,適用于數(shù)據(jù)遷移、報表生成等場景,本文介紹Spring?Batch是什么的相關(guān)知識,感興趣的朋友一起看看吧
    2025-07-07
  • Netty分布式pipeline管道Handler的刪除邏輯操作

    Netty分布式pipeline管道Handler的刪除邏輯操作

    這篇文章主要為大家介紹了Netty分布式pipeline管道Handler的刪除邏輯操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03

最新評論

湖口县| 永春县| 涿州市| 阳原县| 积石山| 应用必备| 侯马市| 伊春市| 斗六市| 阜城县| 峨眉山市| 东海县| 普格县| 墨江| 泰宁县| 灵山县| 高雄市| 射阳县| 若尔盖县| 汽车| 安平县| 周宁县| 醴陵市| 囊谦县| 宁城县| 临夏县| 滦南县| 富平县| 常德市| 望江县| 苏尼特右旗| 三河市| 文化| 宜都市| 福安市| 库伦旗| 蒙山县| 绍兴市| 沿河| 福鼎市| 北流市|