HTML5 文件域+FileReader 分段读取文件

Posted 天马3798

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();

 分段读取文件(四):http://www.cnblogs.com/tianma3798/p/5839869.html

 读取文件三:http://www.cnblogs.com/tianma3798/p/5839810.html

读取文件二:http://www.cnblogs.com/tianma3798/p/5839791.html

读取文件一:http://www.cnblogs.com/tianma3798/p/4355949.html

以上是关于HTML5 文件域+FileReader 分段读取文件的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 文件域+FileReader 分段读取文件并上传-WebSocket

HTML5 文件域+FileReader 分段读取文件并上传-WebSocket

HTML5 文件域+FileReader 分段读取文件并上传到服务器

HTML5 文件域+FileReader 读取文件

HTML5 FileReader对象

HTML5文件读取FileReader及文件读取模块的封装