目錄
1、什么是斷點(diǎn)續(xù)傳
2、分塊文件
3、合并文件
4、?Minio 分布式文件系統(tǒng)整合斷點(diǎn)續(xù)傳
4.1 進(jìn)行文件分塊上傳到 Minio?
4.2 進(jìn)行 Minio 中分塊文件的合并
5、使用 Minio 進(jìn)行斷點(diǎn)續(xù)傳的注意事項(xiàng)
?
????????相信很多小伙伴在上傳下載圖片或者視頻的時(shí)候,突然間(沒錯(cuò)就是這么禿然),斷電或者斷網(wǎng)了,但是等恢復(fù)正常后,之前的圖片或視頻又需要重0開始進(jìn)行上傳或者下載!體驗(yàn)感那可是相當(dāng)?shù)牟顒?,這不,斷點(diǎn)續(xù)傳技術(shù)孕育而生......
1、什么是斷點(diǎn)續(xù)傳
由來:
傳統(tǒng)的文件傳輸方式通常是一次性地將整個(gè)文件進(jìn)行傳輸,如果在傳輸過程中發(fā)生中斷或失敗,需要重新開始傳輸整個(gè)文件,這可能會(huì)浪費(fèi)時(shí)間和帶寬資源。而通過斷點(diǎn)續(xù)傳的機(jī)制,可以在傳輸過程中記錄下已經(jīng)成功傳輸?shù)牟糠?,如果傳輸中斷,則可以從中斷的位置繼續(xù)傳輸,節(jié)省時(shí)間和資源
定義:
斷點(diǎn)續(xù)傳指的是在下載或上傳時(shí),將下載或上傳任務(wù)(一個(gè)文件或一個(gè)壓縮包)人為的劃分為幾個(gè)部分,每一個(gè)部分采用一個(gè)線程進(jìn)行上傳或下載,如果碰到網(wǎng)絡(luò)故障,可以從已經(jīng)上傳或下載的部分開始繼續(xù)上傳下載未完成的部分,而沒有必要從頭開始上傳下載,斷點(diǎn)續(xù)傳可以提高節(jié)省操作時(shí)間,提高用戶體驗(yàn)性
斷點(diǎn)續(xù)傳通常涉及以下幾個(gè)關(guān)鍵要素:
-
傳輸狀態(tài)的保存:需要在傳輸過程中記錄已經(jīng)成功傳輸?shù)牟糠?,通常使用文件或?shù)據(jù)庫來保存?zhèn)鬏敔顟B(tài)信息
-
傳輸中斷的處理:當(dāng)傳輸中斷時(shí),需要能夠檢測到中斷事件,并記錄下中斷的位置信息
-
傳輸?shù)幕謴?fù):在中斷后重新開始傳輸時(shí),根據(jù)記錄的中斷位置信息,可以通過讀取文件或數(shù)據(jù)庫中的狀態(tài)信息,定位到中斷的位置,并從該位置開始繼續(xù)傳輸
-
數(shù)據(jù)校驗(yàn):為確保傳輸?shù)臏?zhǔn)確性,通常會(huì)使用校驗(yàn)和或哈希算法對傳輸?shù)臄?shù)據(jù)進(jìn)行校驗(yàn),以檢測數(shù)據(jù)的完整性
斷點(diǎn)續(xù)傳大致流程圖:
流程解讀:
前端上傳文件前,先將其分成若干塊? >>>>>>??一塊一塊的上傳,上傳中斷后重新上傳,已上傳的分塊則不用再上傳? >>>>>>??各分塊上傳完成最后在服務(wù)端合并文件
2、分塊文件
定義:
分塊文件(Chunked File)是將一個(gè)文件切分為較小的塊或片段的文件格式或存儲(chǔ)方式。每個(gè)塊都是源文件的一部分,通過切分和組合這些塊,可以還原出完整的原始文件
使用場景:
-
分布式存儲(chǔ):在分布式系統(tǒng)中,將大文件切分為多個(gè)塊并存儲(chǔ)在不同的節(jié)點(diǎn)上。這種方式可以提高存儲(chǔ)和讀取的效率,并允許數(shù)據(jù)并行處理
-
塊存儲(chǔ)設(shè)備:某些存儲(chǔ)設(shè)備(如磁盤陣列)將數(shù)據(jù)組織為固定大小的塊,并使用塊地址來訪問和管理數(shù)據(jù)
-
數(shù)據(jù)傳輸和網(wǎng)絡(luò)傳輸:通過將文件切分為多個(gè)塊,可以分批傳輸和處理大文件,從而提高數(shù)據(jù)傳輸?shù)乃俣群涂煽啃?/p>
-
容災(zāi)備份:將文件切分為多個(gè)塊,并存儲(chǔ)在不同的位置或設(shè)備上,以提供容災(zāi)備份和恢復(fù)能力
代碼實(shí)現(xiàn):
首先,我們得指定需要進(jìn)行分塊傳輸?shù)囊曨l文件以及分塊存儲(chǔ)的目的地;同時(shí),因?yàn)槲募枰謮K,所以要定義每個(gè)分塊文件的大小
//1.指定目標(biāo)源文件
File sourceFile = new File("C:\\Users\\DELL\\Videos\\cy01.mp4");
//2.分塊文件的存儲(chǔ)路徑
String chunkPath = "C:\\Users\\DELL\\Videos\\chunk\\";
//2.1分塊文件的大小
int chunkSize = 1024*1024; //兆 MB
//2.2分塊文件的個(gè)數(shù)
int chunkNum = (int) Math.ceil(sourceFile.length()*1.0 / chunkSize); //進(jìn)行向上取整
一開始,該分塊路徑下并沒有任何的文件
????????然后,經(jīng)過上面的定義過后,使用流的方式進(jìn)行讀寫文件數(shù)據(jù)
????????這里,選擇使用 RandomAccessFile類 用于對文件進(jìn)行隨機(jī)訪問,即可以在文件中以任意順序讀取和寫入數(shù)據(jù)。相比于其他文件讀寫類,RandomAccessFile?提供了更靈活的訪問方式,其具有:非順序訪問、可讀寫性、文件編輯與更新、大型文件的處理以及記錄式文件的處理功能
????????總之,RandomAccessFile類?的作用是提供對文件的隨機(jī)訪問功能,可以根據(jù)需要定位到文件的任意位置進(jìn)行讀取和寫入。它適用于需要處理大文件、進(jìn)行非順序訪問以及在特定位置修改數(shù)據(jù)等場景
//3.使用流從源文件上讀數(shù)據(jù),向分塊文件中寫數(shù)據(jù)
byte[] bytes = new byte[1024];
//3.1 讀數(shù)據(jù)
RandomAccessFile readInfo = new RandomAccessFile(sourceFile, "r");
for(int i=0;i<chunkNum;i++){
File chunkFile = new File(chunkPath + i);
//3.2寫數(shù)據(jù)
RandomAccessFile writeInfo = new RandomAccessFile(chunkFile, "rw");
int length;
while ((length=readInfo.read(bytes))!=-1){
writeInfo.write(bytes,0,length);
if(chunkFile.length()>=chunkSize){ //若比定義的塊大,則結(jié)束寫入
break;
}
}
writeInfo.close();
}
readInfo.close();
運(yùn)行結(jié)果:
很顯然,之前 7+ MB 的文件,現(xiàn)在有序的分成了多塊,達(dá)到了預(yù)想的效果
完整代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-500348.html
//1.指定目標(biāo)源文件
File sourceFile = new File("C:\\Users\\DELL\\Videos\\cy01.mp4");
//2.分塊文件的存儲(chǔ)路徑
String chunkPath = "C:\\Users\\DELL\\Videos\\chunk\\";
//2.1分塊文件的大小
int chunkSize = 1024*1024; //兆 MB
//2.2分塊文件的個(gè)數(shù)
int chunkNum = (int) Math.ceil(sourceFile.length()*1.0 / chunkSize); //進(jìn)行向上取整
//3.使用流從源文件上讀數(shù)據(jù),向分塊文件中寫數(shù)據(jù)
byte[] bytes = new byte[1024];
//3.1 讀數(shù)據(jù)
RandomAccessFile readInfo = new RandomAccessFile(sourceFile, "r");
for(int i=0;i<chunkNum;i++){
File chunkFile = new File(chunkPath + i);
//3.2寫數(shù)據(jù)
RandomAccessFile writeInfo = new RandomAccessFile(chunkFile, "rw");
int length;
while ((length=readInfo.read(bytes))!=-1){
writeInfo.write(bytes,0,length);
if(chunkFile.length()>=chunkSize){ //若比定義的塊大,則結(jié)束寫入
break;
}
}
writeInfo.close();
}
readInfo.close();
3、合并文件
定義:
將多個(gè)部分下載的文件塊(或分塊)組合成一個(gè)完整的文件。在文件傳輸過程中,一般會(huì)將大文件分成多個(gè)較小的文件塊進(jìn)行傳輸。當(dāng)其中一個(gè)或多個(gè)文件塊傳輸失敗或中斷時(shí),合并文件的步驟就變得重要
代碼實(shí)現(xiàn):
收集文件塊:首先,需要從不同的來源(例如服務(wù)器或其他傳輸源)收集已經(jīng)成功下載的文件塊。這些文件塊可能以不同的順序或位置存在
//1.指定需要合并的分塊文件
File chunkFile = new File("C:\\Users\\DELL\\Videos\\chunk\\");
//2.源文件
File sourceFile = new File("C:\\Users\\DELL\\Videos\\cy01.mp4");
//3.自定義合并后的文件的名稱以及路徑
File mergeFile = new File("C:\\Users\\DELL\\Videos\\mergeFile.mp4");
//4.取出所有的分塊文件
File[] chunkFiles = chunkFile.listFiles();
確定文件塊順序:根據(jù)文件塊的序號或其他標(biāo)識信息,確定文件塊的正確順序。這是因?yàn)槲募K可能以異步方式傳輸或以不同的順序到達(dá)
注意:這里需要將分塊的文件進(jìn)行排序,然后按順序的進(jìn)行合并;好比源文件是一個(gè)完整的積木,現(xiàn)在被打亂了,分成了很多快小積木,如果將中間部分的小積木放在原來的最底下,那么完整的積木指定是拼不成功的;所以,需要按順序一步步來
//4.1 將數(shù)組轉(zhuǎn)成 list 集合
List<File> chunkFileList = Arrays.asList(chunkFiles);
//4.2進(jìn)行排序
chunkFileList.sort(new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName());
}
});
合并文件塊:將收集到的文件塊按照正確的順序合并到一個(gè)完整的文件中。這涉及將每個(gè)文件塊的內(nèi)容按照其在整個(gè)文件中的位置進(jìn)行追加或插入
//5.遍歷分塊文件,向之前定義的合并文件中進(jìn)行寫數(shù)據(jù)
RandomAccessFile writeInfo = new RandomAccessFile(mergeFile,"rw");
byte[] bytes = new byte[1024];
chunkFileList.stream()
.forEach(new Consumer<File>() {
@Override
public void accept(File chunkSortFile) {
try {
RandomAccessFile readInfo = new RandomAccessFile(chunkSortFile, "r");
int length;
while ((length= readInfo.read(bytes))!=-1){
writeInfo.write(bytes,0,length);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
writeInfo.close();
檢驗(yàn)和校驗(yàn):在合并文件完成后,通常會(huì)進(jìn)行校驗(yàn)以確保合并后的文件完整性。可以使用校驗(yàn)和或哈希算法(如MD5、SHA1等)對整個(gè)文件進(jìn)行校驗(yàn),以驗(yàn)證文件的準(zhǔn)確性和完整性;這里使用MD5進(jìn)行校驗(yàn)前后文件
//6.將合并完成后的文件與源文件進(jìn)行校驗(yàn)
String sourceMD5 = DigestUtils.md5Hex(new FileInputStream(sourceFile));
String mergeMD5 = DigestUtils.md5Hex(new FileInputStream(mergeFile));
if(sourceMD5.equals(mergeMD5)){
System.out.println("文件合并成功!");
}
運(yùn)行結(jié)果:
?可見,合并的文件大小與源文件一致,效果達(dá)成 o(* ̄▽ ̄*)ブ
完整代碼:
//1.指定需要合并的分塊文件
File chunkFile = new File("C:\\Users\\DELL\\Videos\\chunk\\");
//2.源文件
File sourceFile = new File("C:\\Users\\DELL\\Videos\\cy01.mp4");
//3.自定義合并后的文件的名稱以及路徑
File mergeFile = new File("C:\\Users\\DELL\\Videos\\mergeFile.mp4");
//4.取出所有的分塊文件
File[] chunkFiles = chunkFile.listFiles();
if(chunkFiles!=null) {
//4.1 將數(shù)組轉(zhuǎn)成 list 集合
List<File> chunkFileList = Arrays.asList(chunkFiles);
//4.2進(jìn)行排序
chunkFileList.sort(new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName());
}
});
//5.遍歷分塊文件,向之前定義的合并文件中進(jìn)行寫數(shù)據(jù)
RandomAccessFile writeInfo = new RandomAccessFile(mergeFile,"rw");
byte[] bytes = new byte[1024];
chunkFileList.stream()
.forEach(new Consumer<File>() {
@Override
public void accept(File chunkSortFile) {
try {
RandomAccessFile readInfo = new RandomAccessFile(chunkSortFile, "r");
int length;
while ((length= readInfo.read(bytes))!=-1){
writeInfo.write(bytes,0,length);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
writeInfo.close();
//6.將合并完成后的文件與源文件進(jìn)行校驗(yàn)
String sourceMD5 = DigestUtils.md5Hex(new FileInputStream(sourceFile));
String mergeMD5 = DigestUtils.md5Hex(new FileInputStream(mergeFile));
if(sourceMD5.equals(mergeMD5)){
System.out.println("文件合并成功!");
}
}
4、?Minio 分布式文件系統(tǒng)整合斷點(diǎn)續(xù)傳
大致流程圖:
流程解讀:
- 前端對文件進(jìn)行分塊? >>>>>>??前端上傳分塊文件前請求媒資服務(wù)檢查文件是否存在,如果已經(jīng)存
- 在則不再上傳? >>>>>>??如果分塊文件不存在則前端開始上傳? >>>>>> 前端請求媒資服務(wù)上傳分塊
- >>>>>> 媒資服務(wù)將分塊上傳至Minio?>>>>>> 前端將分塊上傳完畢請求媒資服務(wù)合并分塊 >>>>>>
- 媒資服務(wù)判斷分塊上傳完成則請求Minio合并文件 >>>>>> 合并完成校驗(yàn)合并后的文件是否完整,
- 如果不完整則刪除文件
4.1 進(jìn)行文件分塊上傳到 Minio?
? 首先,定義 minio 的地址以及賬號和密碼
MinioClient minioClient =
MinioClient.builder()
//分布式文件 minio 地址
.endpoint("http://localhost:9000")
//對應(yīng)的 minio 賬號以及密碼
.credentials("minioadmin", "minioadmin")
.build();
先是通過傳入的文件后綴,以流的方式獲取該文件的類型,即 contentType;然后通過? ? 獲取本地分塊文件的集合,以動(dòng)態(tài)的獲取分塊的數(shù)量;最后,調(diào)用??Minio Java SDK? 提供的? ? ? ? ? UploadObjectArgs 方法進(jìn)行分塊文件的上傳(這里部分地方就先寫死了)
//1.通過擴(kuò)展名得到媒資類型
ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".mp4");
String streamValue = MediaType.APPLICATION_OCTET_STREAM_VALUE; //默認(rèn)的字節(jié)流類型
if(extensionMatch!=null){
streamValue = extensionMatch.getMimeType();
}
//1.1獲取到本地目錄下的分塊文件的集合
String chunkFilePath = "C:\\Users\\DELL\\Videos\\chunk\\"; //指定本地分塊文件地址
File chunkFile = new File(chunkFilePath);
File[] chunkFileList = chunkFile.listFiles(); //以集合的形式獲取分塊文件
if(chunkFileList!=null) {
for (int i = 0; i < chunkFileList.length; i++) {
//2.文件相關(guān)參數(shù)的傳遞
UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder()
.bucket("mediafiles") //桶的名稱
.filename(chunkFilePath + i)
.object("chunk/" + i) //傳入 minio 中后的對象名
.contentType(streamValue) //設(shè)置媒體文件的類型
.build();
//3.進(jìn)行上傳文件
minioClient.uploadObject(uploadObjectArgs);
System.out.println("上傳第" + i + "個(gè)分塊文件成功!");
}
}
本地文件中:
?Minio 中:
運(yùn)行之后:
?
4.2 進(jìn)行 Minio 中分塊文件的合并
前提引入:
這里使用 ComposeSourse 類型進(jìn)行合并,下面是該類通常的使用場景:
媒體合成:如果您正在開發(fā)一個(gè)多媒體應(yīng)用程序,
ComposeSource
?可以用來表示各種媒體元素的組合,例如音頻、視頻或圖像的集合。您可以將這些元素組合成一個(gè)復(fù)合媒體源文檔合成:如果您正在處理文檔或報(bào)告生成,
ComposeSource
?可以用來表示文本塊、表格、圖表等多個(gè)組成部分。您可以將這些部分組合成一個(gè)完整的文檔或報(bào)告界面元素組合:在用戶界面設(shè)計(jì)中,
ComposeSource
?可以用來表示具有不同樣式和布局的界面元素,例如按鈕、文本字段、標(biāo)簽等。您可以使用?ComposeSource
?來描述界面的不同組成部分,以便靈活地構(gòu)建和渲染用戶界面數(shù)據(jù)結(jié)構(gòu)組合:
ComposeSource
?也可以表示具有層次結(jié)構(gòu)的數(shù)據(jù)組合,例如樹、圖或圖表數(shù)據(jù)。您可以使用?ComposeSource
?來存儲(chǔ)和操作這些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
? 首先,創(chuàng)建一個(gè) ComposeSource 類型的集合,將 minio 中 chunk 目錄下的分塊文件進(jìn)行封裝,? ? 便于之后的統(tǒng)一處理
//1.獲取 minio 中分塊文件的信息
List<ComposeSource> sources = new ArrayList<>();
//2.將需要合并的文件放入 sources 集合進(jìn)行統(tǒng)一處理
String chunkFilePath = "C:\\Users\\DELL\\Videos\\chunk\\"; //指定本地分塊文件地址
File chunkFile = new File(chunkFilePath);
File[] chunkFileList = chunkFile.listFiles(); //以集合的形式獲取分塊文件
if(chunkFileList!=null) {
sources = Stream.iterate(0, i -> ++i)
.limit(chunkFileList.length)
.map(i -> ComposeSource.builder()
.bucket("mediafiles")
.object("chunk/" + i)
.build()).collect(Collectors.toList());
}
? 這里進(jìn)行合并操作,合并之前,需要自定義 object 合并后的文件名(注意:這里的文件后綴名需? ? 要與源文件一致);然后傳入之前被封裝好的分塊文件的集合 sources ,最后調(diào)用 API 進(jìn)行合并
//3.指定合并后,minio 中的文件(自定義名稱或者目錄位置)
ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder()
.bucket("mediafiles")
.object("mergeFile.mp4")
.sources(sources) //指定需要進(jìn)行合并的分塊文件
.build();
//4.進(jìn)行合并文件
minioClient.composeObject(composeObjectArgs);
? 接下來,就到了校驗(yàn)環(huán)節(jié);先使用?Minio Java SDK? 提供的? GetObjectArgs 方法,獲取到? ? ? ? ? Minio 中合并之后文件的數(shù)據(jù)流;然后使用 MD5 分別進(jìn)行 Minio 合并文件與本地源文件的校驗(yàn)
//5.將 minio 中合并后的文件與本地源文件進(jìn)行校驗(yàn)
//5.1進(jìn)行指定分布式文件
GetObjectArgs getObjectArgs = GetObjectArgs.builder()
.bucket("mediafiles")
.object("mergeFile.mp4") //這里是合并后的文件
.build();
//5.2獲取 minio 合并文件中的數(shù)據(jù)流
FilterInputStream minioStream = minioClient.getObject(getObjectArgs);
//6.進(jìn)行校驗(yàn)
//6.1 minio 合并文件
String minio_MD5 = DigestUtils.md5DigestAsHex(inputStream);
//6.2 源文件
String source_MD5 = DigestUtils.md5DigestAsHex(new FileInputStream(new File("C:\\Users\\DELL\\Videos\\cy02.mp4")));
if(minio_MD5.equals(source_MD5)){
System.out.println("合并文件成功!");
}
inputStream.close();
運(yùn)行結(jié)果:
這里有警告,主要是因?yàn)榘姹镜膯栴},這個(gè)問題對合并文件影響不大
以上需要注意的是,有些小伙伴可能會(huì)出現(xiàn)以下的錯(cuò)誤:
java.lang.IllegalArgumentException: source testbucket/chunk/0: size 1048576 must be greater than 5242880
原因分析:minio合并文件默認(rèn)分塊最小5MB,我們將分塊改為5MB再次測試
minio 中合并的文件可正常播放;可見,合并文件成功 o(* ̄▽ ̄*)ブ
文章來源:http://www.zghlxwxcb.cn/news/detail-500348.html
完整代碼:
//1.獲取 minio 中分塊文件的信息
List<ComposeSource> sources = new ArrayList<>();
//2.將需要合并的文件放入 sources 集合進(jìn)行統(tǒng)一處理
String chunkFilePath = "C:\\Users\\DELL\\Videos\\chunk\\"; //指定本地分塊文件地址
File chunkFile = new File(chunkFilePath);
File[] chunkFileList = chunkFile.listFiles(); //以集合的形式獲取分塊文件
if(chunkFileList!=null) {
sources = Stream.iterate(0, i -> ++i)
.limit(chunkFileList.length)
.map(i -> ComposeSource.builder()
.bucket("mediafiles")
.object("chunk/" + i)
.build()).collect(Collectors.toList());
}
//3.指定合并后,minio 中的文件(自定義名稱或者目錄位置)
ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder()
.bucket("mediafiles")
.object("mergeFile.mp4")
.sources(sources) //指定需要進(jìn)行合并的分塊文件
.build();
//4.進(jìn)行合并文件
minioClient.composeObject(composeObjectArgs);
//5.將 minio 中合并后的文件與本地源文件進(jìn)行校驗(yàn)
//5.1進(jìn)行指定分布式文件
GetObjectArgs getObjectArgs = GetObjectArgs.builder()
.bucket("mediafiles")
.object("mergeFile.mp4") //這里是合并后的文件
.build();
//5.2獲取 minio 合并文件中的數(shù)據(jù)流
FilterInputStream inputStream = minioClient.getObject(getObjectArgs);
//6.進(jìn)行校驗(yàn)
//6.1 minio 合并文件
String input_MD5 = DigestUtils.md5DigestAsHex(inputStream);
//6.2 源文件
String out_MD5 = DigestUtils.md5DigestAsHex(new FileInputStream(new File("C:\\Users\\DELL\\Videos\\cy02.mp4")));
if(input_MD5.equals(out_MD5)){
System.out.println("合并文件成功!");
}
inputStream.close();
5、使用 Minio 進(jìn)行斷點(diǎn)續(xù)傳的注意事項(xiàng)
- 分片大小:在進(jìn)行斷點(diǎn)續(xù)傳時(shí),需要將文件拆分為較小的分片。較小的分片大小有助于在連接中斷或錯(cuò)誤發(fā)生時(shí)更輕松地恢復(fù)傳輸。通常建議使用256 KB到1 MB的分片大小
- 分片上傳:將文件按照分片進(jìn)行上傳,而不是一次性上傳整個(gè)文件??梢允褂肕inIO提供的??
putObject
方法來進(jìn)行分片上傳。在上傳每個(gè)分片時(shí),將分片編號和總分片數(shù)作為參數(shù)提供給MinIO客戶端- 斷點(diǎn)續(xù)傳邏輯:在上傳過程中,需要確保在傳輸失敗或連接中斷時(shí)能夠恢復(fù)上傳。為此,可以記錄已成功上傳的分片,并在需要時(shí)從上次中斷的位置繼續(xù)上傳??梢允褂脴?biāo)記來追蹤已上傳的分片編號
- 檢查已上傳的分片:在恢復(fù)上傳過程中,首先需要檢查已上傳的分片,并確定哪些分片需要繼續(xù)上傳??梢允褂肕inIO提供的?
listObjects
方法來列出存儲(chǔ)桶中已經(jīng)上傳的分片- 并發(fā)上傳:為了加快上傳速度,可以考慮使用并發(fā)上傳的方式。使用多個(gè)線程或協(xié)程同時(shí)上傳不同的分片可以提高整體上傳性能。請確保對并發(fā)上傳進(jìn)行適當(dāng)?shù)恼{(diào)度和同步,以避免競爭條件和數(shù)據(jù)沖突
- 對象合并:當(dāng)所有分片都上傳完畢后,需要執(zhí)行分片合并操作將它們合并為完整的對象。可以使用MinIO提供的?
composeObject
方法或其他相應(yīng)的API來執(zhí)行分片合并操作- 錯(cuò)誤處理和重試:上傳過程中可能會(huì)遇到網(wǎng)絡(luò)錯(cuò)誤、連接中斷或其他異常情況。需要合理處理這些錯(cuò)誤,并進(jìn)行重試機(jī)制以確保上傳的可靠性。設(shè)置適當(dāng)?shù)闹卦嚧螖?shù)和重試間隔,以應(yīng)對可能的傳輸問題
到了這里,關(guān)于上傳視頻文件,基于斷點(diǎn)續(xù)傳(整合Minio)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!