1. 程式人生 > >HTML5 檔案域+FileReader 分段讀取檔案(五)

HTML5 檔案域+FileReader 分段讀取檔案(五)

一、預設FileReader會分段讀取File物件,這是分段大小不一定,並且一般會很大

HTML:

複製程式碼
<div class="container">
    <!--文字檔案驗證-->
    <input type="file" id="file" />
    <h4>選擇檔案如下:</h4>
    <blockquote></blockquote>
</div>
複製程式碼

JS:

複製程式碼
//讀取文字檔案例項
var fileBox = document.getElementById('file');
fileBox.onchange 
= function () { showFiles(); } function showFiles() { //獲取選擇檔案的陣列 var fileList = fileBox.files; for (var i = 0; i < fileList.length; i++) { var file = fileList[i]; readFile(file); } } //讀取檔案內容 function readFile(file) { var reader = new FileReader(); //中文windows系統 txt 文字多數預設編碼 gbk
reader.readAsText(file, 'gbk'); reader.onprogress = function (e) { //預設情況下也是分段讀取, //預設情況下,每次分段大小不確定,不同瀏覽器也不相同 //第一次讀取比較小 Google每段:8028160(7.65625mb) FF每段:786432(768mb) IE下:4096(4k) console.info(e); } reader.onload = function (e) { var result = reader.result; console.info(e.loaded); } }
複製程式碼

二、分段讀取文字檔案+進度條例項,並解決IE瀏覽器崩潰問題

HTML:

複製程式碼
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">分段讀取檔案:</div>
        <div class="panel-body">
            <input  type="file" id="file" />
            <input type="button" id="abort" value="中斷" />
            <input type="button" id="containue" value="繼續讀取檔案" />
            <p>
                <label>讀取進度:</label><progress id="Progress"  style="width:300px;" value="0" max="100"></progress>
            </p>
            <p id="Percent"></p>
            <p id="Status"></p><hr />
            <blockquote style="word-break:break-all;"></blockquote>
        </div>
    </div>
</div>
複製程式碼

JS:

複製程式碼
var read = {
    //初始化繫結
    init: function () {
        var _this = this;
        _this.status = document.getElementById('Status');
        _this.progress = document.getElementById('Progress');
        _this.percent = document.getElementById('Percent');

        document.getElementById('file').onchange = _this.fileHandler;
        document.getElementById('abort').onclick = _this.abortHandler;
        document.getElementById('containue').onclick = _this.containueHandler;

        _this.loaded = 0;
        //每次讀取1M
        _this.step = 3 * 2;
    },
    //當有選中檔案時,事件處理
    fileHandler: function (e) {
        //讀取檔案
        var _this = read;
        //獲取上傳檔案
        var file = _this.file = this.files[0];
        var reader = _this.reader = new FileReader();
        //繫結資訊和事件
        _this.total = file.size;
        _this.isabort = false;//標記正在讀取還是以已經中止
        reader.onprogress = _this.onProgress;
        reader.onabort = _this.onAbort;
        reader.onerror = _this.onError;
        reader.onload = _this.onLoad;
        //從頭讀取一塊
        _this.readBlob(0);
        $('blockquote').empty();
    },
    //中斷 操作
    abortHandler: function (e) {
        var _this = read;
        if (_this.reader) {
            console.log('讀取操作操作中止,' + _this.loaded);
            _this.isabort = true;
            _this.reader.abort();
        }
    },
    //繼續操作
    containueHandler: function (e) {
        var _this = read;
        _this.isabort = false;
        console.info('繼續:' + _this.loaded);
        //繼續讀取
        _this.readBlob(_this.loaded);
    },
    //讀取過程
    onProgress: function (e) {
        var _this = read;
        if (e.lengthComputable == false)
            return;
        _this.loaded += e.loaded;
        //更新進度條
        var value = (_this.loaded / _this.total) * 100;
        _this.percent.innerText = value;
        _this.progress.value = value;
    },
    //中止上傳事件
    onAbort: function () {
        var _this = read;
        //console.log('讀取操作操作中止,'+_this.loaded);
    },
    //當出現異常時
    onError: function () { },
    //讀取成功  結束
    onLoad: function (e) {
        var _this = read;
        var result = _this.reader.result;
        $('blockquote').append(result);
        //判斷是否已經讀到最後,如果沒有繼續讀取
        if (_this.loaded < _this.total) {
            //IE 瀏覽器下,事件觸發速度太快,頁面容易出現假死現象,解決方案延緩事件觸發
            setTimeout(function () {
                _this.readBlob(_this.loaded);
            }, 10);
            //直接使用在Google,FF沒問題
            // _this.readBlob(_this.loaded);
        } else {
            _this.loaded = _this.total;
        }
    },
    readBlob: function (start) {
        var _this = read;
        if (_this.isabort)
            return;
        var file = _this.file;
        var blob = file.slice(start, start + _this.step);
        _this.reader.readAsText(blob, 'gbk');
    }
};
read.init();
複製程式碼

三、分段讀取檔案為ArrayBuffer+進度條顯示

HTML,同上

JS:

複製程式碼
var read = {
    //初始化繫結
    init: function () {
        var _this = this;
        _this.status = document.getElementById('Status');
        _this.progress = document.getElementById('Progress');
        _this.percent = document.getElementById('Percent');

        document.getElementById('file').onchange = _this.fileHandler;
        document.getElementById('abort').onclick = _this.abortHandler;

        _this.loaded = 0;
        //每次讀取1M
        //_this.step = 1024 * 1024;
        //_this.step = 1024;
        _this.step = 1024;
        _this.times = 0;
    },
    //當有選中檔案時,事件處理
    fileHandler: function (e) {
        //讀取檔案
        var _this = read;
        //獲取上傳檔案
        var file = _this.file = this.files[0];
        var reader = _this.reader = new FileReader();
        //繫結資訊和事件
        _this.total = file.size;
        reader.onloadstart = _this.onLoadStrart;
        reader.onprogress = _this.onProgress;
        reader.onabort = _this.onAbort;
        reader.onerror = _this.onError;
        reader.onload = _this.onLoad;
        //reader.onloadend = _this.onLoadEnd;
        //從頭讀取一塊
        _this.readBlob(0);
        $('blockquote').empty();
    },
    //中斷
    abortHandler: function (e) {
        var _this = read;
        if (_this.reader) {
            _this.reader.abort();
        }
    },
    //開始讀取檔案
    onLoadStrart: function () { },
    //讀取過程
    onProgress: function (e) {
        var _this = read;
        //e.loaded 當前讀取的數量
        //e.total 讀取總量
        _this.loaded += e.loaded;
        //更新進度條
        _this.progress.value = (_this.loaded / _this.total) * 100;
    },
    //中止上傳事件
    onAbort: function () { },
    //當出現異常時
    onError: function () { console.log('讀取出錯'); },
    //讀取成功  結束
    onLoad: function (e) {
        var _this = read;
        var reader = _this.reader;
        // console.info(_this.loaded + '---' + _this.total);
        //console.info(reader.result); //ArrayBuffer 陣列
        //console.info(reader.result.byteLength); //ArrayBuffer 陣列 的長度

        //轉換成  Int8Array 型別
        //var b = new Int8Array(reader.result);
        //轉換成 Int32Arrary 型別
        var b = new Int32Array(reader.result);
        console.info(b); //ArrayBuffer 陣列 的長度
        $('blockquote').append(b.toString());
        //判斷是否已經讀到最後,如果沒有繼續讀取
        if (_this.loaded < _this.total) {
            _this.readBlob(_this.loaded);
        } else {
            _this.loaded = _this.total;
        }
    },
    //讀取結束時 ,每次讀取成功結束或呼叫abord
    onLoadEnd: function (e) {
        //console.log('讀取結束');
    },
    readBlob: function (start) {
        var _this = read;
        var blob,
            file = _this.file;
        _this.times += 1;
        console.info('start:' + start);
        blob = file.slice(start, start + _this.step);
        _this.reader.readAsArrayBuffer(blob);
    }
};
read.init();