筆者之前遇了好幾處需要處理文件流的場景哩盲,以及互相轉(zhuǎn)換狈醉,這邊深入的學(xué)習(xí)了一下它們的概念,區(qū)別以及互相轉(zhuǎn)換苗傅,閱讀本文你將了解前端常見的文件流格式,以及相互轉(zhuǎn)換的思路嘶炭。
1.概念
File
一般情況之下File
對象是input
標(biāo)簽選擇文件之后的FileList
對象逊桦,也可以是也可以是來自由拖放操作生成的 DataTransfer
對象,或者來自 HTMLCanvasElement
上的 mozGetAsFile() API
睡陪。
File
是特殊的Blob
匿情,可以處理Blob
的函數(shù)必然可以處理Blob
,比如說汁果, FileReader
, URL.createObjectURL()
, createImageBitmap() (en-US)
, 及 XMLHttpRequest.send()
都能處理 Blob
和 File
玲躯。
總結(jié):File
是一個(gè)特殊的Blob
對象鲸伴。具體API
參見MDN File
Base64
Base64
是一種由64
個(gè)可打印字符組成的對二進(jìn)制編碼的規(guī)則(binary-to-text)
Base64解決了什么問題晋控?
Base64
就是為了解決各系統(tǒng)以及傳輸協(xié)議中二進(jìn)制不兼容的問題而生的。為什么Base64
能實(shí)現(xiàn)兼容呢仲吏?主要還是因?yàn)楦骷蚁到y(tǒng)只能保證ASIIC
的基礎(chǔ)字符蝌焚,所以Base64
就是取了其中的64個(gè) 參見MDN Base64。
Base64
的算法:
1.將原始數(shù)據(jù)每三個(gè)字節(jié)作為一組许帐,每個(gè)字節(jié)是8個(gè)bit毕谴,所以一共是 24 個(gè) bit
2.將 24 個(gè) bit 分為四組,每組 6 個(gè) bit
3.在每組前面加補(bǔ) 00涝开,將其補(bǔ)全成四組8個(gè)bit,到此步拄养,原生數(shù)據(jù)的3個(gè)字節(jié)已經(jīng)變成4個(gè)字節(jié)了银舱,增大了將近30%
4.根據(jù)Base64碼表得到擴(kuò)展后每個(gè)字節(jié)的對應(yīng)符號
小tips:
關(guān)于Base64結(jié)尾的’=‘,而且有時(shí)候是一個(gè)有時(shí)候是兩個(gè)棋弥,這是因?yàn)閎ase64是以三個(gè)字符為一組操软,所以當(dāng)不滿三個(gè)的時(shí)候就會用’=‘補(bǔ),缺一個(gè)補(bǔ)一個(gè)’=‘家乘,缺兩個(gè)補(bǔ)兩個(gè)’=’藏澳。
其實(shí)在實(shí)際開發(fā)中,我們得到的是DataURL前面一般會有data:image/jpeg;base64
,需要注意的是,之后的才是真正的數(shù)據(jù)翔悠。
Blob
Blob
是一個(gè)表示不可變野芒,原始數(shù)據(jù)的文件對象狞悲,它的數(shù)據(jù)可以按文本或者二進(jìn)制的格式進(jìn)行讀取妇斤,也可以轉(zhuǎn)換成 ReadableStream
來用于數(shù)據(jù)操作。 具體API參見MDN Blob
可以用Blob
實(shí)現(xiàn)對大文件進(jìn)行分片上傳站超。
ArrayBuffer
ArrayBuffer
對象用來表示通用的、固定長度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)融求。
它是一個(gè)字節(jié)數(shù)組算撮,通常在其他語言中稱為“byte array”
。
而ArrayBuffer
的內(nèi)容不能直接被操作 茅糜,而是要通過類型數(shù)組對象或 DataView
對象來操作素挽,將緩沖區(qū)中的數(shù)據(jù)表示為特定的格式狸驳,并通過這些格式來讀寫緩沖區(qū)的內(nèi)容。
2.互相轉(zhuǎn)換
在日常開發(fā)中我們經(jīng)常遇到一些api或者組件對文件類型有要求撰糠,只這時(shí)候就需要對這些文件類型進(jìn)行轉(zhuǎn)化辩昆。
在這在之前先介紹一下一個(gè)JS BOM API FileReader
FileReader
可以讀取Blob
對象所以同時(shí)也能讀取File
對象,并且FileReader
提供了輸出ArrayBuffer
Base64
的接口术辐。
下面直接貼一些轉(zhuǎn)換代碼:
File轉(zhuǎn)Base64:
let reader = new FileReader();
reader.readAsDataURL(file[0])
console.log(reader)
Base64轉(zhuǎn)Blob:
const dataURItoBlob = (dataURI) => {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: mimeString});
}
Blob轉(zhuǎn)ArrayBuffer:
let blob = new Blob([1,2,3,4])
let reader = new FileReader();
reader.onload = function(result) {
console.log(result);
}
reader.readAsArrayBuffer(blob);
Buffer轉(zhuǎn)Blob:
let blob = new Blob([buffer])
Base64轉(zhuǎn)File:
const base64ConvertFile = function (urlData, filename) {
if (typeof urlData != 'string') {
return;
}
var arr = urlData.split(',')
var type = arr[0].match(/:(.*?);/)[1]
var fileExt = type.split('/')[1]
var bstr = atob(arr[1])
var n = bstr.length
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], 'filename.' + fileExt, {
type: type
});
}
總結(jié):
前端常見的文件流格式有Blob
File
Base64
ArrayBuffer
辉词,其中File
是特殊的Blob
對象,大部分轉(zhuǎn)換都可以通過JS BOM API FileReader實(shí)現(xiàn)猾骡。