實(shí)現(xiàn)前后端視頻文件的斷點(diǎn)續(xù)傳功能

實(shí)現(xiàn)IO流拆分合并的集合功能(多個文本文件進(jìn)行合并/一個視頻文件切割成單個文件/多個視頻流合并成單個視頻文件/前后端視頻文件的斷點(diǎn)續(xù)傳功能)

package com.example.yygoods.controller;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

import java.io.*;

@RestController
public class SequenceStream {
    Vector<InputStream> vectorStreams = new Vector<>();
    /*
     * 實(shí)現(xiàn)多個文本文件進(jìn)行合并
     * Vector作用和數(shù)組類似炉菲,存儲數(shù)據(jù)蠢古,功能會比數(shù)組強(qiáng)大,如: 可以返回枚舉類型數(shù)據(jù)
     * 注釋:SequenceInputStream參數(shù)必須是枚舉類型的數(shù)據(jù)
     * vectorStreams.elements()返回此向量的組件的枚舉
     **/
    @GetMapping("/streamMerge")
    public String streamMerge () {
        try {
            String UPLOAD_DIR = System.getProperty("user.dir");
            InputStream inputStream_a = new FileInputStream(UPLOAD_DIR + "\\1.txt");
            InputStream inputStream_b = new FileInputStream(UPLOAD_DIR + "\\2.txt");
            vectorStreams.add(inputStream_a);
            vectorStreams.add(inputStream_b);
            SequenceInputStream sis = new SequenceInputStream(vectorStreams.elements());
            OutputStream outputStream = new FileOutputStream(UPLOAD_DIR + "\\merge.txt");
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = sis.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.close();
            sis.close();
        } catch (Exception e) {
            return "Error merging files: " + e.getMessage();
        }
        return "index";
    }
    /*
     * 實(shí)現(xiàn)一個視頻文件切割成單個文件
     * RandomAccessFile可以在任意地方進(jìn)行讀寫文件
     * getFilePointer():返回文件記錄指針的當(dāng)前位置
     * seek(long pos):將文件記錄指針定位到pos位置
     **/
    @GetMapping("/splitVideo")
    public String splitVideo () {
        try {
            String UPLOAD_DIR = System.getProperty("user.dir");
            File source_file = new File(UPLOAD_DIR + "\\file.mp4");
            File chunk_file = new File(UPLOAD_DIR + "\\chunk");
            if(!chunk_file.exists()){
                chunk_file.mkdirs();
            }
            //切片大小設(shè)置為100kb
            long chunkSize = 102400;
            //分塊數(shù)量
            long chunkNum = (long) Math.ceil(source_file.length() * 1.0 / chunkSize);
            System.out.println("分塊總數(shù):"+chunkNum);
            //緩沖區(qū)大小
            byte[] b = new byte[1024];
            //使用RandomAccessFile訪問文件
            RandomAccessFile source_file_rf = new RandomAccessFile(source_file, "r");
            for (int i = 0; i < chunkNum; i++) {
                //創(chuàng)建分塊文件,如果存在刪除,在創(chuàng)建新建文件
                File file = new File(UPLOAD_DIR + "\\chunk\\" + i);
                if(file.exists()){
                    file.delete();
                }
                boolean newFile = file.createNewFile();
                // 創(chuàng)建成功廷臼,讀取原文件把流寫入到新建的新建文件中
                if (newFile) {
                    RandomAccessFile chunk_file_rf = new RandomAccessFile(file, "rw");
                    int len = -1;
                    while ((len = source_file_rf.read(b)) != -1) {
                        chunk_file_rf.write(b, 0, len);
                        if (file.length() >= chunkSize) {
                            break;
                        }
                    }
                    chunk_file_rf.close();
                }
            }
            source_file_rf.close();
        } catch (Exception e) {
            return "Error merging files: " + e.getMessage();
        }
        return "index";
    }
    /*
     * 實(shí)現(xiàn)多個視頻流合并成單個視頻文件
     **/
    @GetMapping("/mergVideo")
    public String mergVideo () {
        try {
            String UPLOAD_DIR = System.getProperty("user.dir");
            File origin_file = new File(UPLOAD_DIR + "\\file.mp4");
            File merge_file = new File(UPLOAD_DIR + "\\merge_file.mp4");
            File chunk_file = new File(UPLOAD_DIR + "\\chunk");
            if(merge_file.exists()) {
                merge_file.delete();
            }
            //創(chuàng)建新的合并文件
            merge_file.createNewFile();
            //使用RandomAccessFile讀寫文件
            RandomAccessFile raf_write = new RandomAccessFile(merge_file, "rw");
            //指針指向文件頂端
            raf_write.seek(0);
            //緩沖區(qū)
            byte[] b = new byte[1024];
            //分塊列表
            File[] fileArray = chunk_file.listFiles();
            // 轉(zhuǎn)成集合,便于排序
            List<File> fileList = Arrays.asList(fileArray);
            System.out.println("集合文件:" + fileList);
            // 從小到大排序
            Collections.sort(fileList, new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName());
                }
            });
            System.out.println("排序的集合文件:" + fileList);
            // 遍歷集合文件,讀取每個文件的內(nèi)容再寫入到新文件中
            for (File chunkFile : fileList) {
                RandomAccessFile raf_read = new RandomAccessFile(chunkFile, "rw");
                int len = -1;
                while ((len = raf_read.read(b)) != -1) {
                    raf_write.write(b, 0, len);
                }
                raf_read.close();
            }
            raf_write.close();
            //校驗(yàn)文件
            FileInputStream fileInputStream = new FileInputStream(origin_file);
            FileInputStream mergeFileStream = new FileInputStream(merge_file);
            //取出原始文件的md5
            String originalMd5 = DigestUtils.md5Hex(fileInputStream);
            //取出合并文件的md5進(jìn)行比較
            String mergeFileMd5 = DigestUtils.md5Hex(mergeFileStream);
            if (originalMd5.equals(mergeFileMd5)) {
                System.out.println("合并文件成功");
            } else {
                System.out.println("合并文件失敗");
            }
        } catch (Exception e) {
            return "Error merging files: " + e.getMessage();
        }
        return "index";
    }
    /*
     * 實(shí)現(xiàn)前后端視頻文件的斷點(diǎn)續(xù)傳功能
     * Vector作用和數(shù)組類似,存儲數(shù)據(jù)谆焊,功能會比數(shù)組強(qiáng)大,如: 可以返回枚舉類型數(shù)據(jù)
     * 注釋:SequenceInputStream參數(shù)必須是枚舉類型的數(shù)據(jù)
     * vectorStreams.elements()返回此向量的組件的枚舉
     **/
    @PostMapping("/merge-files")
    public String mergeFiles(@RequestParam MultipartFile file, @RequestParam Integer index, @RequestParam Integer total, @RequestParam String name) {
        try {
            InputStream inputStream = file.getInputStream();
            vectorStreams.add(inputStream);
            if (index < total) {
                return "success" + index;
            } else {
                SequenceInputStream sis = new SequenceInputStream(vectorStreams.elements());
                // 假設(shè)你想把合并后的流保存為一個新文件
                String UPLOAD_DIR = System.getProperty("user.dir");
                File outfile = new File(UPLOAD_DIR + "\\" + name);
                FileOutputStream fos = new FileOutputStream(outfile);

                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = sis.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                }
                sis.close();
                fos.close();
                vectorStreams.clear();
                return "success";
            }
        } catch (Exception e) {
            return "Error merging files: " + e.getMessage();
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浦夷,一起剝皮案震驚了整個濱河市辖试,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌劈狐,老刑警劉巖罐孝,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異懈息,居然都是意外死亡肾档,警方通過查閱死者的電腦和手機(jī)摹恰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門辫继,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俗慈,你說我怎么就攤上這事姑宽。” “怎么了闺阱?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵炮车,是天一觀的道長。 經(jīng)常有香客問我,道長瘦穆,這世上最難降的妖魔是什么纪隙? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮扛或,結(jié)果婚禮上绵咱,老公的妹妹穿的比我還像新娘。我一直安慰自己熙兔,他們只是感情好悲伶,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著住涉,像睡著了一般麸锉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舆声,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天花沉,我揣著相機(jī)與錄音,去河邊找鬼纳寂。 笑死主穗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的毙芜。 我是一名探鬼主播忽媒,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼腋粥!你這毒婦竟也來了晦雨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤隘冲,失蹤者是張志新(化名)和其女友劉穎闹瞧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體展辞,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奥邮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了罗珍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洽腺。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖覆旱,靈堂內(nèi)的尸體忽然破棺而出蘸朋,到底是詐尸還是另有隱情,我是刑警寧澤扣唱,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布藕坯,位于F島的核電站团南,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏炼彪。R本人自食惡果不足惜吐根,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辐马。 院中可真熱鬧佑惠,春花似錦、人聲如沸齐疙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贞奋。三九已至赌厅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間轿塔,已是汗流浹背特愿。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勾缭,地道東北人揍障。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像俩由,于是被迫代替她去往敵國和親毒嫡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容