官术网_书友最值得收藏!

4.3 讀取文件

通過使用File和FileList對象的相關(guān)屬性可以獲取用戶所選擇文件的基本信息,除了這兩個(gè)對象外,HTML 5新增的API中還提供了FileReader對象,該對象是一個(gè)接口,它允許在客戶端讀取文件的數(shù)據(jù),并且可以在JavaScript腳本中使用。

4.3.1 認(rèn)識FileReader接口

FileReader接口專門用來讀取文件,根據(jù)W3C的定義,它提供一些讀取文件的方法與一個(gè)包含讀取結(jié)果的事件模型。它的主要作用是將文件讀取到內(nèi)存,并且提供相應(yīng)的方法來讀取文件中的數(shù)據(jù),下面從以下三個(gè)方面進(jìn)行介紹。

1.判斷瀏覽器是否支持FileReader

前面已經(jīng)提到過,并不是所有的瀏覽器都提供了對HTML 5功能的支持,F(xiàn)ileReader屬于HTML 5功能的一部分,因此,在使用FileReader之前,可以檢測當(dāng)前瀏覽器是否支持FileReader。

判斷瀏覽器是否支持FileReader,如果瀏覽器支持FileReader接口,那么該瀏覽器有一個(gè)位于Windows對象下的FileReader構(gòu)造函數(shù),如果這個(gè)構(gòu)造函數(shù)存在,那么就可以通過new實(shí)例化一個(gè)FileReader來使用。檢測代碼如下。

    if ( typeof FileReader == 'undefined' ) {
        alert( "您的瀏覽器未實(shí)現(xiàn)FileReader接口" );
    } else {
        alert("當(dāng)前瀏覽器運(yùn)行環(huán)境正常,能夠支持FileReader接口。");
        var reader = new FileReader();
        //others
    }

上述代碼首先判斷瀏覽器所支持的FileReader是否等于undefined,是或不是都會(huì)彈出提示。如果支持FileReader接口,則會(huì)創(chuàng)建FileReader的實(shí)例對象。當(dāng)訪問不同的文件時(shí),每調(diào)用一次FileReader接口都將返回一個(gè)新的FileReader對象,這樣才會(huì)訪問不同文件中的數(shù)據(jù),因此,必須創(chuàng)建不同的FileReader接口實(shí)例對象。

2.FileReader接口的方法

FileReader接口提供了4個(gè)方法,其中三個(gè)方法用來讀取文件,一個(gè)方法用來讀取中斷,方法說明如表4-2所示。

表4-2 FileReader接口的方法

調(diào)用表4-2中的方法讀取內(nèi)容時(shí),無論讀取文件是否成功,方法都不會(huì)返回讀取的結(jié)果,而是將存儲在result屬性中,并且result屬性只能位于FileReader接口所提供的onload事件中。

3.FileReader接口的事件

FileReader接口中提供了一套完整的事件模型,用于監(jiān)視讀取文件時(shí)的各個(gè)狀態(tài),如表4-3所示。

表4-3 FileReader接口的事件

相關(guān)人員調(diào)用FileReader接口提供的方法讀取文件時(shí),會(huì)伴隨著發(fā)生一系列的事件,它們表示讀取文件時(shí)不同的讀取狀態(tài),下面通過一個(gè)簡單的練習(xí)演示FileReader接口的事件執(zhí)行的先后順序。

【練習(xí)4】

本次練習(xí)根據(jù)用戶選擇的圖片路徑顯示圖片,并且顯示不同瀏覽器下所執(zhí)行的事件順序,步驟如下。

(1)添加并設(shè)計(jì)新的網(wǎng)頁,在頁面中添加文件選擇框和執(zhí)行操作的按鈕,并且為操作按鈕添加事件。代碼如下。

    選擇一個(gè)文件:<input type="file" id="selFile" accept="image/jpg" />
    <input type="button" id="btnGetFile" value="事件" onClick="GetOper()" />

(2)繼續(xù)向網(wǎng)頁中添加用于處理操作的結(jié)果元素,img用來顯示圖片,ol元素顯示事件執(zhí)行順序。代碼如下。

    <img id="myPic" />
    <ol id="msgInfo"></ol>

(3)選擇文件后單擊【事件】按鈕觸發(fā)Click事件調(diào)用GetOper()函數(shù),該函數(shù)中首先獲取用戶選擇的文件,接著創(chuàng)建FileReader接口實(shí)例對象,再調(diào)用readAsDataURL()方法讀取文件。然后分別為FileReader接口的各個(gè)事件添加代碼,在onload事件中,通過e.target.result屬性的結(jié)果值綁定到顯示圖片的img元素中,在其他事件中直接綁定處理的結(jié)果。部分腳本代碼如下。

    function GetOper()
    {
        var file = document.getElementById("selFile").files[0];
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e){
            document.getElementById("myPic").src = e.target.result;//或者this.result獲取
            document.getElementById("msgInfo").innerHTML += "<li>觸發(fā)了onload事件。</li>";
        }
        reader.onprogress = function(e){
            document.getElementById("msgInfo").innerHTML += "<li>觸發(fā)了onprogress事件。</li>";
        }
        //省略其他事件的處理
    }

(4)不同瀏覽器由于使用的內(nèi)核不同,上傳圖片的大小不同,因此,執(zhí)行的事件順序也不會(huì)完全相同。選擇文件后直接單擊【事件】按鈕查看事件執(zhí)行順序,如圖4-13和圖4-14所示分別為Maxthon瀏覽器和Opera瀏覽器的效果。

圖4-13 Maxthon瀏覽器運(yùn)行效果

圖4-14 Opera瀏覽器運(yùn)行效果

從圖4-13和圖4-14中可以看出,在執(zhí)行FileReader接口的事件時(shí)并不是所有的事件都會(huì)執(zhí)行。針對這些事件,還有一些內(nèi)容需要注意,說明如下。

(1)大部分的文件讀取過程都集中在onprogress事件中,這個(gè)事件消耗時(shí)間最長。

(2)如果文件在讀取過程中出現(xiàn)異常或中止,那么onprogress事件將結(jié)束,直接觸發(fā)onerror或onabort事件,而不再觸發(fā)onload事件。

(3)onload事件是文件讀取成功時(shí)觸發(fā),而onloadend雖然也是文件操作成功時(shí)觸發(fā),但該事件不論文件讀取是否成功,都將觸發(fā)。因此,想要正確獲取文件數(shù)據(jù),必須在onload事件中編寫代碼。

4.3.2 讀取二進(jìn)制文件

FileReader接口所提供的readAsBinaryString()方法是將文件讀取為二進(jìn)制字符串,通常是將它傳送到后端,后端可以通過這段字符串存儲文件。

readAsBinaryString()方法的使用很簡單,只要將一個(gè)要讀取的文件file作為參數(shù)傳入即可,這樣讀取的結(jié)果將保存到result屬性中。

【練習(xí)5】

本次練習(xí)中,用戶首先選擇一個(gè)文件,然后單擊頁面中的按鈕顯示二進(jìn)制文件內(nèi)容,最后將結(jié)果顯示到textarea元素中,實(shí)現(xiàn)步驟如下。

(1)添加并設(shè)計(jì)新的網(wǎng)頁,在頁面的合適位置添加選擇文件框,然后分別添加三個(gè)按鈕元素,分別執(zhí)行讀取二進(jìn)制文件、讀取圖像文件和讀取文本文件的操作,并且需要為讀取二進(jìn)制文件的按鈕添加onClick事件屬性。代碼如下。

    選擇文件:<input type="file" id="selFile" /><br/><br/>
    <input type="button" id="btnGetBinaryFileInfo" value="讀取二進(jìn)制文件" onClick="GetBinaryFile()" />&nbsp;&nbsp;
    <input type="button" id="btnGetPicInfo" value="讀取圖像文件" />&nbsp; &nbsp;
    <input type="button" id="btnGetFileInfo" value="讀取文本文件" />

(2)GetBinaryFile()函數(shù)用來讀取選擇文件的二進(jìn)制內(nèi)容,首先獲取用戶選擇的文件對象,通過判斷對象是否為空確定是否選擇了文件。如果選擇了文件則創(chuàng)建FileReader接口的對象,然后將file對象作為參數(shù)傳入所調(diào)用的readAsBinaryString()方法中,并且在onload事件中獲取返回的結(jié)果。代碼如下。

    function GetBinaryFile()
    {
        var file = document.getElementById("selFile").files[0];
        if(file==null || file=='undefined'){    //判斷是否選擇了文件,沒有選擇
            alert("您還沒有選擇文件,請選擇文件。");
        }else{                                    //如果選擇了文件
            var reader = new FileReader();
            reader.readAsBinaryString(file);
            reader.onload = function(e){
                document.getElementById("readResult").innerHTML = this.result;
            }
        }
    }

(3)運(yùn)行頁面選擇文件查看效果,其中,程序文件、文本文件、圖像和壓縮包等都屬于二進(jìn)制文件。如圖4-15所示為Maxthon瀏覽器下讀取壓縮包的二進(jìn)制文件,如圖4-16所示為Firefox瀏覽器下讀取圖像的二進(jìn)制文件。

圖4-15 Maxthon瀏覽器運(yùn)行效果

圖4-16 Firefox瀏覽器運(yùn)行效果

試一試

另外,同一個(gè)文件在不同的瀏覽器所讀取出的二進(jìn)制文件的內(nèi)容會(huì)有所不同,在Opera瀏覽器下讀取的內(nèi)容都非常簡短,感興趣的讀者可以進(jìn)行測試。

4.3.3 顯示預(yù)覽圖像

FileReader接口所提供的readAsDataURL()方法將文件讀取為一段以data開頭的字符串,這段字符串實(shí)質(zhì)上就是DataURL,即一種將小文件直接嵌入文檔的方案,小文件通常是指圖像與html等格式的文件。

【練習(xí)6】

本次練習(xí)主要調(diào)用FileReader接口的readAsDataURL()方法,不通過后臺而即時(shí)實(shí)現(xiàn)圖片預(yù)覽的功能,其中允許用戶選擇多個(gè)圖片文件,單擊按鈕提交后將顯示這些文件的縮略效果圖。

(1)繼續(xù)更改練習(xí)5中的頁面,首先將文件選擇框的multiple屬性的值設(shè)置為true,然后向名稱是“讀取圖像文件”的按鈕中添加onClick事件屬性。代碼如下。

    選擇文件:<input type="file" id="selFile" multiple="true" /><br/><br/>
    <input type="button" id="btnGetBinaryFileInfo" value="讀取二進(jìn)制文件" onClick="GetBinaryFile()" disabled />&nbsp;&nbsp;
    <input type="button" id="btnGetPicInfo" value="讀取圖像文件" onClick="GetPicFile()" />&nbsp;&nbsp;
    <input type="button" id="btnGetFileInfo" value="讀取文本文件" />

(2)刪除用于顯示二進(jìn)制文件內(nèi)容的textarea元素,向頁面中添加顯示圖片列表的span元素。代碼如下。

    <span id="showInfo"></span>

(3)GetPicFile()文件獲取用戶選擇的文件,并且進(jìn)行判斷,如果選擇的文件符合是圖像的要求,則將其顯示到頁面中,否則會(huì)彈出提示。代碼如下。

    function GetPicFile()
    {
        var filelist = document.getElementById("selFile");    //獲取選擇的文件
        if(filelist.files.length==0)                    //如果選擇文件列表為空
        {
            alert("請選擇您要查看的圖像");
        }else{
            for (var i = 0; i < filelist.files.length; i++) {//循環(huán)顯示文件
                var file = filelist.files[i];            //獲取單個(gè)文件
                var imageType = /image.*/;                //聲明文件類型
                if (!file.type.match(imageType)) {        //如果上傳文件不合法
                    alert(file.name+"不是圖像文件,因此不能上傳。");
                    continue;
                }
                var reader = new FileReader();        //實(shí)例FileReader接口對象
                reader.onload = function(e){        //顯示圖像
                    document.getElementById("showInfo").innerHTML +=
                    "<img src="+e.target.result+" width=200 height=150 style='padding-right:50px; padding-bottom:20px;' />";
                };
                reader.readAsDataURL(file);
            }
        }
    }

(4)運(yùn)行頁面查看效果,所有圖像選擇完成后單擊【讀取圖像文件】按鈕進(jìn)行預(yù)覽查看,效果如圖4-17所示。

圖4-17 顯示預(yù)覽圖像的效果

4.3.4 讀取文本文件

除了readAsBinaryString()方法和readAsDataURL()方法外,F(xiàn)ileReader接口還提供了一種讀取文件的方法——readAsText()方法。readAsText()方法專門用來讀取文本文件,該方法常用的參數(shù)有兩個(gè):第一個(gè)參數(shù)是file類型,表示要讀取的文件;第二個(gè)參數(shù)是字符串類型,表示讀取文件時(shí)使用的編碼,默認(rèn)值是UTF-8。

【練習(xí)7】

本練習(xí)通過使用readAsText()方法實(shí)現(xiàn)讀取用戶選擇文本文件內(nèi)容的功能,其文件選擇框與練習(xí)5一樣,一次只允許用戶選擇一個(gè)文件進(jìn)行讀取,實(shí)現(xiàn)步驟如下。

(1)添加并設(shè)計(jì)新的頁面,更改或重新添加頁面的內(nèi)容。如下代碼演示了文件框執(zhí)行操作。

選擇文件:<input type="file" id="selFile" /><br/><br/>
    <input type="button" id="btnGetFileInfo" value="讀取文本文件" onClick="GetFile()" />

(2)練習(xí)6中通過指定span元素的有關(guān)屬性的值預(yù)覽圖片,本次練習(xí)繼續(xù)使用span元素顯示內(nèi)容,相關(guān)代碼不再顯示。

(3)JavaScript腳本中的GetFile()函數(shù)實(shí)現(xiàn)了文本文件內(nèi)容的讀取,在該函數(shù)中首先判斷用戶是否選擇文件,如果沒有選擇文件則彈出提示。如果已經(jīng)選擇了文件,則在else語句中判斷所選擇的文件是否符合類型,如果不符合則彈出提示,否則在FileReader接口的onload事件中指定顯示的內(nèi)容。GetFile()函數(shù)的代碼如下。

    function GetFile()
    {
        var file = document.getElementById("selFile").files[0];
        if(file==null || file=='undefined'){                //如果沒有選擇文件
            alert("您還沒有選擇文件,請選擇文件。");
        }else{
            var txtType = /text.*/;
            if (!file.type.match(txtType)) {        //如果選擇的文件不符合類型
                alert(file.name+"不是文本文件,請重新選擇文件進(jìn)行上傳。")
                return;
            }
            var reader = new FileReader();
            reader.readAsText(file);
            reader.onload = function(e){                    //顯示文件內(nèi)容
                document.getElementById("showInfo").innerHTML = this.result;
            }
        }
    }

(4)運(yùn)行頁面,在多個(gè)瀏覽器中選擇文件進(jìn)行測試。這些瀏覽器由于文件編碼、頁面編碼以及兼容性等問題,可能會(huì)導(dǎo)致所讀取的文件有的瀏覽器能正常顯示,有些瀏覽器則顯示亂碼,如圖4-18和圖4-19所示分別了Maxthon瀏覽器和Firefox瀏覽器中的效果。

圖4-18 Maxthon瀏覽器讀取文本文件

圖4-19 Firefox瀏覽器讀取文本文件

(5)重新向GetFile()函數(shù)中添加內(nèi)容,在readAsText()方法的第二個(gè)參數(shù)中指定編碼格式。代碼如下。

    reader.readAsText(file,"gb2312");

(6)重新在各個(gè)瀏覽器中選擇文件進(jìn)行測試,如圖4-20和圖4-21所示分別為Maxthon瀏覽器和Opera瀏覽器編碼后的效果。

圖4-20 編碼后Maxthon瀏覽器效果

圖4-21 編碼后Opera瀏覽器效果

(7)在GetFile()函數(shù)中通過txtType變量聲明文本文件類型,文本文件類型常見的有兩種形式:一種是“text/plain”格式的文件,通常以.txt結(jié)尾;另一種是“text/html”文件,以.html結(jié)尾。如圖4-22所示顯示了讀取某磁盤下File Reader.html文件在Opera瀏覽器中的顯示效果,注意編碼格式。

圖4-22 讀取.html格式的文本文件

主站蜘蛛池模板: 当涂县| 吐鲁番市| 天镇县| 武陟县| 自贡市| 郸城县| 蚌埠市| 盐城市| 同仁县| 阿瓦提县| 洛宁县| 北安市| 子洲县| 苏州市| 宁德市| 靖州| 临桂县| 高密市| 荆州市| 枣强县| 潜江市| 徐汇区| 海门市| 景德镇市| 迁安市| 行唐县| 丰城市| 安泽县| 静安区| 衡阳市| 灯塔市| 砀山县| 改则县| 新乐市| 绍兴县| 定陶县| 江北区| 沐川县| 绥中县| 呼和浩特市| 沙坪坝区|