フロントエンドファイルのシャーディングと結合
1. 背景の紹介
現在、大きなファイルをアップロードまたはダウンロードする場合、ブレークポイントでアップロードを再開する効果を得るために、部分的にアップロードまたはダウンロードすることがほとんどです。そうしないと、ネットワークが中断されると、以前にアップロードまたはダウンロードされたデータの一部が失われ、すべてのデータを再度アップロードまたはダウンロードする必要があります。
2. シャーディング
Blob.slice
シャーディング操作 jsは、ソース BLOB の指定されたバイト範囲内のデータを含む新しい Blob オブジェクトを作成するために使用される既製の API をすでに提供しています。
文法:
const blob = instanceOfBlob.slice(start , end , contentType)
start
:optional
このパラメータは Blob 内の添え字を表し、新しい Blob にコピーされる最初のバイトの開始位置を示します。負の数値を渡すと、オフセットはデータの末尾から先頭まで計算されます。たとえば、-10 は BLOB の最後の 10 番目のバイトになります。デフォルト値は 0 です。渡した開始の長さがソース BLOB の長さより大きい場合、長さが 0 でデータのない Blob オブジェクトが返されます。
end
:optional
このパラメータは Blob のインデックスを表します。インデックス -1 に対応するバイトは、新しい Blob にコピーされる最後のバイトになります。負の数値を渡すと、オフセットはデータの末尾から先頭まで計算されます。たとえば、-10 は BLOB の最後の 10 番目のバイトになります。デフォルト値は元の長さ (サイズ)
contentType
:optional
新しい Blob に新しいドキュメント タイプを割り当てます。これにより、その type 属性が渡された値に設定されます。デフォルト値は空の文字列です。
3. 組み合わせ
Blob()
この組み合わせは、コンストラクターを使用して直接初期化できます
。構文:
const aBlob = new Blob( array, options );
array
: これは、ArrayBuffer、ArrayBufferView、Blob、DOMString およびその他のオブジェクト、または Blob に配置される他の同様のオブジェクトの混合で構成される配列です。DOMStrings は UTF-8 としてエンコードされます。
options
: はオプションの BlobPropertyBag ディクショナリであり、次の 2 つのプロパティを指定できます。
type
: デフォルト値は "" で、BLOB に配置される配列コンテンツの MIME タイプを表します。endings
: デフォルト値は「透明」で、行終端文字 \n を含む文字列の書き込み方法を指定するために使用されます。これは 2 つの値のいずれかです。「ネイティブ」は、行終端文字がホスト オペレーティング システムのファイル システムに適した改行に変更されることを意味し、「透過」は、BLOB に保存された終端文字が変更されないままになることを意味します。規格外
4. 完全なコード
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<label>
<input id="input" type="file" onchange="fileChange(event)"/>
</label>
<script>
// 文件大于20MB时,设置每个分片大小为20MB
const chunkSize = 20 * 1024 * 1024;
function fileChange(e) {
// 定义一个数组存放所有的分片
const chunks = [];
// 获取文件
const file = e.target.files[0]
const name = file.name
const type = file.type
// 计算总共有多少个分片
const totalChunks = Math.ceil(file.size / chunkSize);
// 进行分片
for (let i = 0; i < totalChunks; i++) {
// 利用slice方法获取每个分片
const start = i * chunkSize;
// 使用Math.min避免超出文件大小
const end = Math.min(file.size, start + chunkSize);
const blob = file.slice(start, end, type);
// 将每个分片添加到数组中
chunks.push(blob);
}
// 在此可以分片提交文件给后端了,具体实现接口请自己解决
console.log(chunks)
// 合并时chunks应该从接口获取,这里默认你已经获取完文件数据并放入chunks中(不要忘记在请求时设置responseType为blob)
// 组合
const newBlob = new Blob(chunks, {
type
});
newBlob.name = name
console.log(newBlob)
// 组合下载测试
const aTag = document.createElement('a')
aTag.download = name
aTag.href = URL.createObjectURL(newBlob)
// 自动点击创建的标签
aTag.click()
}
</script>
</body>
</html>