本地文件,本地文件管理

本地文件,本地文件管理,HTML5读取本地文件 一旦调用了以上某个方法读取文件后,我们可以监听以上任何一个事件来获得进度、结果等。

本地文件,本地文件管理

本地文件,本地文件管理,HTML5读取本地文件

一旦调用了以上某个方法读取文件后,我们可以监听以上任何一个事件来获得进度、结果等。

预览本地图片

这里主要用到FileReader的readAsDataURL方法,通过将图片数据读取成Data URI的方法,将图片展示出来。

function fileSelect2(e) {
 e = e || window.event;
 var files = this.files;
 var p = document.getElementById('preview2');
 for(var i = 0, f; f = files[i]; i++) {
 var reader = new FileReader();
 reader.onload = (function(file) {
 return function(e) {
 var span = document.createElement('span');
 span.innerHTML = ' img width="100" src="'+ this.result +'" alt="'+ file.name +'" / ';
 p.insertBefore(span, null);
 })(f);
 //读取文件内容
 reader.readAsDataURL(f);
document.getElementById('files2').addEventListener('change', fileSelect2, false);

调用FileReader的readAsDataURL接口时,浏览器将异步读取文件内容,通过给FileReader实例监听一个onload事件,数据加载完毕后,在onload事件处理中,通过reader的result属性即可获得文件内容。

预览文本文件

这里主要用到FileReader的readAsText,对于诸如mimeType为text/plain、text/html等文件均认为是文本文件,即mineType为text开头都可以用这个方法来预览。

function fileSelect3(e) {
 e = e || window.event;
 var files = this.files;
 var p = document.getElementById('preview3');
 for(var i = 0, f; f = files[i]; i++) {
 var reader = new FileReader();
 reader.onload = (function(file) {
 return function(e) {
 var div = document.createElement('div');
 div.className = "text"
 div.innerHTML = encodeHTML(this.result);
 p.insertBefore(div, null);
 })(f);
 //读取文件内容
 reader.readAsText(f);
document.getElementById('files3').addEventListener('change', fileSelect3, false);

PS:由于需要在页面上预览文本,所以则需要对文件中的html特殊字符进行实体编码,避免浏览器解析文件中的html代码。

监控读取进度

既然FileReader是异步读取文件内容,那么就应该可以监听它的读取进度。

事实上,FileReader的onloadstart以及onprogress等事件,可以用来监听FileReader的读取进度。

在onprogress的事件处理器中,有一个ProgressEvent对象,这个事件对象实际上继承了Event对象,提供了三个只读属性:

lengthComputable loaded total

通过以上几个属性,即可实时显示读取进度,不过需要注意的是,此处的进度条是针对单次读取的进度,即一次readAsBinaryString等方法的读取进度。

var input4 = document.getElementById('file4');
var bar = document.getElementById('progress-bar');
var progress = document.getElementById('progress');
function startHandler(e) {
 bar.style.display = 'block';
function progressHandler(e) {
 var percentLoaded = Math.round((e.loaded / e.total) * 100);
 if (percentLoaded 100) {
 progress.style.width = percentLoaded + '%';
 progress.textContent = percentLoaded + '%';
function loadHandler(e) {
 progress.textContent = '100%';
 progress.style.width = '100%';
function fileSelect4(e) {
 var file = this.files[0];
 if(!file) {
 alert('请选择文件!');
 return false;
 if(file.size 500 * 1024 * 1024) {
 alert('文件太大,请选择500M以下文件,防止浏览器崩溃!');
 return false;
 progress.style.width = '0%';
 progress.textContent = '0%';
 var reader = new FileReader();
 reader.onloadstart = startHandler;
 reader.onprogress = progressHandler;
 reader.onload = loadHandler;
 reader.readAsBinaryString(this.files[0]);
input4.onchange = fileSelect4;

有的时候,一次性将一个大文件读入内存,并不是一个很好的选择(如果文件太大,可能直接导致浏览器崩溃),上述的监听进度示例就有可能在文件太大的情况下崩溃。

更稳健的方法是分段读取!

分段读取文件

HTML5 File Api提供了一个slice方法,允许分片读取文件内容。

function readBlob(start, end) {
 var files = document.getElementById('file5').files;
 if(!files.length) {
 alert('请选择文件');
 return false;
 var file = files[0],
 start = parseInt(start, 10) || 0,
 end = parseInt(end, 10) || (file.size - 1);
 var r = document.getElementById('range'),
 c = document.getElementById('content');
 var reader = new FileReader();
 reader.onloadend = function(e) {
 if(this.readyState == FileReader.DONE) {
 c.textContent = this.result;
 r.textContent = "Read bytes: " + (start + 1) + " - " + (end + 1) + " of " + file.size + " bytes";
 var blob;
 if(file.webkitSlice) {
 blob = file.webkitSlice(start, end + 1);
 } else if(file.mozSlice) {
 blob = file.mozSlice(start, end + 1);
 } else if(file.slice) {
 blob = file.slice(start, end + 1);
 reader.readAsBinaryString(blob);
document.getElementById('file5').onchange = function() {
 readBlob(10, 100);
}

本例使用了FileReader的onloadend事件来检测读取成功与否,如果用onloadend则必须检测一下FileReader的readyState,因为read abort时也会触发onloadend事件,如果我们采用onload,则可以不用检测readyState。

分段读取进度

那分段读取一个大文件时,如何监控整个文件的读取进度呢?

这种情况下,因为我们调用了多次FileReader的文件读取方法,跟上文一次性把一个文件读到内存中的情况不大相同,不能用onprogress来监控。

我们可以监听onload事件,每次onload代表每个片段读取完毕,我们只需要在onload中计算已读取的百分比就可以了!

var bar2 = document.getElementById('progress-bar2');
var progress2 = document.getElementById('progress2');
var input6 = document.getElementById('file6');
var block = 1 * 1024 * 1024; // 每次读取1M
// 当前文件对象
var file;
// 当前已读取大小
var fileLoaded;
// 文件总大小
var fileSize;
// 每次读取一个block
function readBlob2() {
 var blob;
 if(file.webkitSlice) {
 blob = file.webkitSlice(fileLoaded, fileLoaded + block + 1);
 } else if(file.mozSlice) {
 blob = file.mozSlice(fileLoaded, fileLoaded + block + 1);
 } else if(file.slice) {
 blob = file.slice(fileLoaded, fileLoaded + block + 1);
 } else {
 alert('不支持分段读取!');
 return false;
 reader.readAsBinaryString(blob);
// 每个blob读取完毕时调用
function loadHandler2(e) {
 fileLoaded += e.total;
 var percent = fileLoaded / fileSize;
 if(percent 1) {
 // 继续读取下一块
 readBlob2();
 } else {
 // 结束
 percent = 1;
 percent = Math.ceil(percent * 100) + '%';
 progress2.innerHTML = percent;
 progress2.style.width = percent;
function fileSelect6(e) {
 file = this.files[0];
 if(!file) {
 alert('文件不能为空!');
 return false;
 fileLoaded = 0;
 fileSize = file.size;
 bar2.style.display = 'block';
 // 开始读取
 readBlob2();
var reader = new FileReader();
// 只需监听onload事件
reader.onload = loadHandler2;
input6.onchange = fileSelect6

在chrome浏览器上测试时,如果直接以file://xxx这种形式访问demo,会出现FileReader读取不到内容的情况,表现为FileReader的result为空或者FileReader根本就没有去读取文件内容,FileReader各个事件没有触发;

这种情况我想应该是类似于chrome不允许添加本地cookie那样,chrome也不允许以file://xxx这种页面上的js代码访问文件内容;

解决办法很简单,只需要将测试文件放到一个web服务器上,以http://xxx形式访问即可。

http://www.html5rocks.com/en/tutorials/file/dndfiles/

转:http://hushicai.com/2014/03/29/html5-du-qu-ben-di-wen-jian.html

标题:本地文件,本地文件管理|http://www.wc10086.cn/412742.html

本文来自网络,不代表本站立场,转载请注明出处!