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

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() 方法來返回文件記錄指針的當(dāng)前位置。
  • 訪問模式:在創(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)))//目標(biāo)文件信息
                    .build();
            sources.add(composeSource);
        }
        ComposeObjectArgs composeObjectArgs = ComposeObjectArgs
                                                        .builder()
                                                        .bucket("testbucket")
                                                        .object("merge01.npm")//目標(biāo)文件
                                                        .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中redis增刪查以及清理緩存的案例

    java中redis增刪查以及清理緩存的案例

    這篇文章主要介紹了java中redis增刪查以及清理緩存的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 超詳細講解Java秒殺項目登陸模塊的實現(xiàn)

    超詳細講解Java秒殺項目登陸模塊的實現(xiàn)

    這是一個主要使用java開發(fā)的秒殺系統(tǒng),項目比較大,所以本篇只實現(xiàn)了登陸模塊,代碼非常詳盡,感興趣的朋友快來看看
    2022-03-03
  • 詳解Java中“==”與equals()的區(qū)別

    詳解Java中“==”與equals()的區(qū)別

    這篇文章主要介紹了詳解Java中“==”與equals()的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 如何把Java程序窗口在屏幕中間顯示

    如何把Java程序窗口在屏幕中間顯示

    大家在日常Java開發(fā)中,可能會需要把程序窗口定位在屏幕中間,那該如何操作呢,下面來一起看看。
    2016-08-08
  • springboot 項目使用jasypt加密數(shù)據(jù)源的方法

    springboot 項目使用jasypt加密數(shù)據(jù)源的方法

    Jasypt 是一個 Java 庫,它允許開發(fā)者以最小的努力為他/她的項目添加基本的加密功能,而且不需要對密碼學(xué)的工作原理有深刻的了解。接下來通過本文給大家介紹springboot 項目使用jasypt加密數(shù)據(jù)源的問題,一起看看吧
    2021-11-11
  • 使用maven項目pom.xml文件配置打包功能和靜態(tài)資源文件自帶版本號功能

    使用maven項目pom.xml文件配置打包功能和靜態(tài)資源文件自帶版本號功能

    在Maven項目中,通過pom.xml文件配置打包功能,可以控制構(gòu)建過程,生成可部署的包,同時,為了緩存控制與版本更新,可以在打包時給靜態(tài)資源文件如JS、CSS添加版本號,這通常通過插件如maven-resources-plugin實現(xiàn)
    2024-09-09
  • Jmeter設(shè)置全局變量token過程圖解

    Jmeter設(shè)置全局變量token過程圖解

    這篇文章主要介紹了Jmeter設(shè)置全局變量token過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • 使用json字符串插入節(jié)點或者覆蓋節(jié)點

    使用json字符串插入節(jié)點或者覆蓋節(jié)點

    這篇文章主要介紹了使用json字符串插入節(jié)點或者覆蓋節(jié)點的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中的跨域和@CrossOrigin注解的作用詳解

    Java中的跨域和@CrossOrigin注解的作用詳解

    這篇文章主要介紹了Java中的跨域和@CrossOrigin注解的作用詳解,跨域,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制,需要的朋友可以參考下
    2023-12-12
  • SpringBoot XSS攻擊的常見形式與防范方法

    SpringBoot XSS攻擊的常見形式與防范方法

    XSS攻擊是指攻擊者在Web頁面的輸入數(shù)據(jù)中插入惡意腳本,當(dāng)其他用戶瀏覽該頁面時,這些腳本就會在用戶的瀏覽器上執(zhí)行,可能導(dǎo)致信息泄露、會話劫持、惡意操作等安全風(fēng)險,本文給大家介紹了SpringBoot XSS攻擊的常見形式與防范方法,需要的朋友可以參考下
    2024-11-11

最新評論