web前端-在迷惘中的探索HTML5(三)文件操作FileReader

簡(jiǎn)介

在HTML5中竟趾,文件選擇標(biāo)簽file增加了如下兩個(gè)屬性:

  • multiple:設(shè)定當(dāng)前元素可以選取多個(gè)文件略水。
  • accept:設(shè)定當(dāng)前選擇器可以選擇的MIME類型或后綴名猖辫。
<input type="file" multiple name="" id="myfilePhoto" value="" accept="image/jpg, image/png">

于此同時(shí)饵婆,其出現(xiàn)了FileReader對(duì)象伞鲫,使用FileReader對(duì)象,web應(yīng)用程序可以異步的讀取存儲(chǔ)在用戶計(jì)算機(jī)上的文件(或者原始數(shù)據(jù)緩沖)內(nèi)容,可以使用File對(duì)象或者Blob對(duì)象來指定所要處理的文件或數(shù)據(jù)。

FileReader:是window對(duì)象的一個(gè)構(gòu)造函數(shù),用于讀取文件選擇標(biāo)簽選擇的File的Dom對(duì)象抛姑。即用來把文件選擇的信息讀入內(nèi)存赞厕,并且讀取文件中的數(shù)據(jù)。其接口提供了一個(gè)異步API定硝,使用該API可以在瀏覽器主線程中異步訪問文件系統(tǒng)皿桑,讀取文件中的數(shù)據(jù)。為了安全FileReader可以讀取表單上已經(jīng)選擇的文件蔬啡,不能讀取本地文件诲侮,它以二進(jìn)制信息的方式讀取表單文件:主要用于大文件的信息讀取。

特點(diǎn):

  1. 讀取后箱蟆,二進(jìn)制信息在瀏覽器內(nèi)存中沟绪,批量的向服務(wù)器進(jìn)行傳輸。
  1. 一般要配合后臺(tái)程序空猜,第三方插件共同完成
  2. 斷點(diǎn)下載和斷點(diǎn)上傳

使用介紹

創(chuàng)建FileReader對(duì)象

想要?jiǎng)?chuàng)建一個(gè)FileReader對(duì)象,很簡(jiǎn)單,如下:

var fr = new FileReader();
FileReader的狀態(tài)常量:

|常量名 | 值 | 描述
|-
|EMPTY | 0 | 還沒有加載任何數(shù)據(jù).
|LOADING | 1 | 數(shù)據(jù)正在被加載.
|DONE | 2 | 已完成全部的讀取請(qǐng)求.

FileReader接口的方法

FileReader接口有5個(gè)方法绽慈,其中4個(gè)用來讀取文件恨旱,另一個(gè)用來中斷讀取。無論讀取成功或失敗坝疼,方法并不會(huì)直接返回讀取結(jié)果搜贤,這一結(jié)果存儲(chǔ)在result屬性中。

FileReader接口的方法:

|方法名 | 參數(shù) | 描述
|-
|readAsArrayBuffer | file | 將文件讀取為一個(gè)ArrayBuffer對(duì)象以表示所讀取文件的內(nèi)容.
|readAsBinaryString | file | 將文件讀取為二進(jìn)制編碼
|readAsText | file,[encoding] | 將文件讀取為文本
|readAsDataURL | file | 將文件讀取為DataURL钝凶,讀取的內(nèi)容是加密以后的本地文件路徑
|abort | (none) | 終端讀取操作

FileReader的屬性:

|屬性名 | 類型 | 描述
|-
|error | DOMError | 在讀取文件時(shí)發(fā)生的錯(cuò)誤. 只讀.
|readyState | unsigned short | 表明FileReader對(duì)象的當(dāng)前狀態(tài). 值為State constants中的一個(gè). 只讀
|result | jsval | 讀取到的文件內(nèi)容.這個(gè)屬性只在讀取操作完成之后才有效,并且數(shù)據(jù)的格式取決于讀取操作是由哪個(gè)方法發(fā)起的. 只讀.

FileReader接口事件

FileReader接口包含了一套完整的事件模型仪芒,用于捕獲讀取文件時(shí)的狀態(tài)。

FileReader接口的事件:

|事件 | 描述
|-
|onabort | 中斷
|onerror | 出錯(cuò)
|onloadstart | 開始
|onprogress | 正在讀取
|onload | 成功讀取
|onloadend | 讀取完成耕陷,無論成功失敗

實(shí)例說明一切:

講完這些大家其實(shí)還是不知道怎么用掂名,于是,實(shí)例來說明一切:

<!-- multiple多個(gè)文件 -->
<input type="file" multiple name="" id="myfilePhoto" value="" accept="image/jpg, image/png">
<ul class="fileUl"></ul>
<script>
    document.getElementById('myfilePhoto').addEventListener("change",function(){
        var inputFile = document.getElementById('myfilePhoto');
        for(var i = 0; i<inputFile.files.length ;i++){
            var fr = new FileReader(); // 這個(gè)FileReader應(yīng)該對(duì)應(yīng)于每一個(gè)讀取的文件都需要重新new一個(gè)
            var files = inputFile.files[i]; // files可以獲取當(dāng)前文件輸入框中選擇的所有文件哟沫,返回列表
            fr.readAsDataURL(files); // 讀取的內(nèi)容是加密以后的本地文件路徑
            fr.onload = function(e){ // 數(shù)據(jù)讀取完成時(shí)觸發(fā)onload對(duì)應(yīng)的響應(yīng)函數(shù)
                // e.target是FileReader等同于fr
                var ulLi = document.createElement('li');
                var ulLiA = document.createElement('a');
                var ulLiimg = document.createElement('img');
                ulLiimg.src = e.target.result
                ulLiA.appendChild(ulLiimg);
                ulLi.appendChild(ulLiA);
                console.log(document.getElementsByClassName('fileUl'))
                document.getElementsByClassName('fileUl')[0].appendChild(ulLi)
            }       
        }
    });
</script>
<script>
    function updateSize() {
        var nBytes = 0;
        var oFiles = document.getElementById("uploadInput").files;
        var nFiles = oFiles.length;
        for (var nFileId = 0; nFileId < nFiles; nFileId++) {
            nBytes += oFiles[nFileId].size;
        }
        var sOutput = nBytes + " bytes";
        var aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
        var nMultiple = 0, nApprox = nBytes / 1024;

        for ( ; nApprox > 1; nApprox /= 1024, nMultiple++) {
            sOutput = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + nBytes + " bytes)";
        }

        document.getElementById("fileNum").innerHTML = nFiles;
        document.getElementById("fileSize").innerHTML = sOutput;
    }
</script>
<p>
    <input id="uploadInput" type="file" name="myFiles" onchange="updateSize();" multiple>
    選擇的文件數(shù):<span id="fileNum">0</span>
    總共大薪让铩:<span id="fileSize">0</span>
</p>

注意:在遍歷時(shí)把 var fileReader = new FileReader(); 放到了循環(huán)之外,會(huì)導(dǎo)致了 Uncaught InvalidStateError: Failed to execute 'readAsDataURL' on 'FileReader': The object is already busy reading Blobs.錯(cuò)誤,這個(gè)FileReader應(yīng)該對(duì)應(yīng)于每一個(gè)讀取的文件都需要重新new一個(gè)南用。
onload只在所有數(shù)據(jù)讀取成功完成時(shí)觸發(fā)膀钠,并且結(jié)果也只在onload之后才有。
問題解釋:因?yàn)槟忝看窝h(huán)如果只new了一次相當(dāng)與你只創(chuàng)建一個(gè)fileReader對(duì)象裹虫,可是我們每次循環(huán)時(shí)肿嘲,拿到的文件信息卻是不同的,這就好比你雇了一個(gè)員工筑公,要求他同時(shí)去打掃衛(wèi)生間又打掃辦公室又去澆花雳窟,他只能先干完一件才能去干另一件,所以它就會(huì)給你報(bào)錯(cuò):The object is already busy reading Blobs.對(duì)象已經(jīng)在忙著閱讀Blobs-即忙著處理不可變的類似文件對(duì)象的原始數(shù)據(jù)匣屡。你一定會(huì)疑問我是for循環(huán)一次完成了胺饩取?你別忘了fr.onload是一個(gè)異步的捣作,你for一次完成誉结,但是處理信息并沒有完成,這就是你指揮員工命令已完成券躁,但是惩坑,員工干活卻還在干,因?yàn)楦苫钜彩且獣r(shí)間的也拜。

FileReader接口的使用

實(shí)例結(jié)束再來個(gè)大點(diǎn)案例:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">  
        var result=document.getElementById("result");  
        var file=document.getElementById("file");  
          
        //判斷瀏覽器是否支持FileReader接口  
        if(typeof FileReader == 'undefined'){  
            result.InnerHTML="<p>你的瀏覽器不支持FileReader接口以舒!</p>";  
            //使選擇控件不可操作  
            file.setAttribute("disabled","disabled");  
        }  
          
        function readAsDataURL(){  
            //檢驗(yàn)是否為圖像文件  
            var file = document.getElementById("file").files[0];  
            if(!/image\/\w+/.test(file.type)){  
                alert("看清楚,這個(gè)需要圖片慢哈!");  
                return false;  
            }  
            var reader = new FileReader();  
            //將文件以Data URL形式讀入頁面  
            reader.readAsDataURL(file);  
            reader.onload=function(e){  
                var result=document.getElementById("result");  
                //顯示文件  
                result.innerHTML='![](' + this.result +')';  
            }  
        }  
          
        function readAsBinaryString(){  
            var file = document.getElementById("file").files[0];  
            var reader = new FileReader();  
            //將文件以二進(jìn)制形式讀入頁面  
            reader.readAsBinaryString(file);  
            reader.onload=function(f){  
                var result=document.getElementById("result");  
                //顯示文件  
                result.innerHTML=this.result;  
            }  
        }  
          
        function readAsText(){  
            var file = document.getElementById("file").files[0];  
            var reader = new FileReader();  
            //將文件以文本形式讀入頁面  
            reader.readAsText(file);  
            reader.onload=function(f){  
                var result=document.getElementById("result");  
                //顯示文件  
                result.innerHTML=this.result;  
            }  
        }  
    </script>  
    <p>  
        <label>請(qǐng)選擇一個(gè)文件:</label>  
        <input type="file" id="file" />  
        <input type="button" value="讀取圖像" onclick="readAsDataURL()" />  
        <input type="button" value="讀取二進(jìn)制數(shù)據(jù)" onclick="readAsBinaryString()" />  
        <input type="button" value="讀取文本文件" onclick="readAsText()" />  
    </p>  
    <div id="result" name="result"></div>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔓钟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子卵贱,更是在濱河造成了極大的恐慌滥沫,老刑警劉巖侣集,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異兰绣,居然都是意外死亡肚吏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門狭魂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人党觅,你說我怎么就攤上這事雌澄。” “怎么了杯瞻?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵镐牺,是天一觀的道長。 經(jīng)常有香客問我魁莉,道長睬涧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任旗唁,我火速辦了婚禮畦浓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘检疫。我一直安慰自己讶请,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布屎媳。 她就那樣靜靜地躺著夺溢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烛谊。 梳的紋絲不亂的頭發(fā)上风响,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音丹禀,去河邊找鬼状勤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛湃崩,可吹牛的內(nèi)容都是我干的荧降。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼攒读,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼朵诫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起薄扁,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤剪返,失蹤者是張志新(化名)和其女友劉穎废累,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脱盲,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邑滨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钱反。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掖看。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖面哥,靈堂內(nèi)的尸體忽然破棺而出哎壳,到底是詐尸還是另有隱情,我是刑警寧澤尚卫,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布归榕,位于F島的核電站,受9級(jí)特大地震影響吱涉,放射性物質(zhì)發(fā)生泄漏刹泄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一怎爵、第九天 我趴在偏房一處隱蔽的房頂上張望特石。 院中可真熱鬧,春花似錦疙咸、人聲如沸县匠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乞旦。三九已至,卻和暖如春题山,著一層夾襖步出監(jiān)牢的瞬間兰粉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工顶瞳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玖姑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓慨菱,卻偏偏與公主長得像焰络,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子符喝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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