HTML5 檔案域+FileReader 分段讀取檔案(五)
阿新 • • 發佈:2018-12-17
一、預設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 文字多數預設編碼 gbkreader.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();