HTML5 File Access

文件访问

介绍

  • File API
  • FileReader API
  • Filesystem & FileWriter API
  • Blob constructing
  • Blob URLs
  • Example
  • 扩展阅读

使用File APIs读取文件

规范提供的从local filesystem 访问文件的几个接口:

  • File: 一个单独的文件;提供了诸如文件名,文件大小,mimetype,以及一个到文件句柄的引用。
  • FileList: File对象的一个类似数组的序列。(想象一下多文件上传或者直接从桌面系统拽一个文件夹的情形)
  • Blob: 允许把文件转换成字节数值。

检测浏览器对File API的支持情况

方法1: 检测File, FileReader, FileList, Blob属性是否存在

<script type='text/javascript'>
  function supports_fileapi() {
  	// 检查各种File API的支持情况
  	if (window.File && window.FileReader && window.FileList && window.Blob) {
    	// 所有的File APIs都支持
    } else {
    	alert('浏览器对File APIs没有全部支持!');
    }
  }
</script>

使用Input表单元素选择文件

<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
     	
<script type='text/javascript'>
  function handleFileSelect(evt) {
    var files = evt.target.files;
    var output = [];
    for (var i=0, f; f = files[i]; i++) {
      output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') -', 
        f.size, ' 字节, 最后修改: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>');
    }
      document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }
  document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

使用拖拽方式选择文件

function handleFileSelect2(evt) {
  evt.stopPropagation();  evt.preventDefault();
  var files = evt.dataTransfer.files;  var output = [];
  for (var i=0, f; f = files[i]; i++) {
    output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') -', 
      f.size, ' 字节, 最后修改: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>');
  }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
  evt.stopPropagation();  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy';
}
var dropZone =  document.getElementById('drop-zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect2, false);
把文件拖拽到这里

FileReader

FileReader包含四种异步读取文件的方式:

  • FileReader.readAsBinaryString(Blob|File) - result属性包含的是file/blob的二进制字符串形式的数据。每个字节由一个0-255的整数表示。
  • FileReader.readAsText(Blob|File, opt_encoding) - result属性包含的是以文本方式表示的file/blob数据。默认情况下,字符串以'UTF-8'编码方式解码。使用opt_encoding参数可以指定一个不同的格式。
  • FileReader.readAsDataURL(Blob|File) - result属性包含的是以data URL编码的file/blob数据。
  • FileReader.readAsArrayBuffer(Blob|File) - result属性包含的是以ArrayBuffer对象表示的file/blob数据。

一旦这些read方法被调用,onloadstart, onprogress, onload, onabort, onerror, onloadend就可以被用来追踪进度。

readAsDataURL Example

function handleFileSelect3(evt) {
  var files = evt.target.files;
  for (var i=0, f; f = files[i]; i++) {
    if (!f.type.match('image.*')) {
      continue;
    }
    var reader = new FileReader();
    reader.onload = (function(theFile) {
        return function(e) {
          // Render thumnial
          var span = document.createElement('span');
          span.innerHTML = ['<img class="thumb" src="', e.target.result,
          '" title="', escape(theFile.name), '"/>'].join('');
          document.getElementById('thumbnails').insertBefore(span, null);
        };
      })(f);
    reader.readAsDataURL(f);	
  }
}
	

文件切片

Slicing File

File接口提供了slice方法支持把文件切成不同的片段,第一个参数是起始的字节数,第二个参数是结束的字节数,还有一个可选的内容类型字符串可以作为第三个参数:

var blob = file.slice(startingByte, endingByte);
reader.readAsBinary(blob);      
			

Slice Example

function readBlob(opt_startByte, opt_stopByte) {
  var file = document.getElementById('files4').files[0];
  var start = parseInt(opt_startByte) || 0;
  var stop = parseInt(opt_stopByte) || file.size - 1;
  var reader = new FileReader();
  reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) {
      document.getElementById('byte_content').textContent = evt.target.result;
      document.getElementById('byte_range').textContent = 
          ['Read bytes: ', start + 1, ' - ', stop + 1,
           ' of ', file.size, ' byte file'].join('');
    }
  };

  var blob = file.slice(start, stop + 1);
  reader.readAsBinaryString(blob);
}
	
读取字节数:

监视文件读取进度

可以使用onloadstartonprogress事件来监视读取进度

function handleFileSelect5(evt) {
  reader = new FileReader();
  reader.onerror = errorHandler;
  reader.onprogress = updateProgress;
  reader.onabort = function(e) {
    alert('文件读取操作被取消');
  };
  reader.onloadstart = function(e) {
    document.getElementById('progress_bar').className = 'loading';
  };
  reader.onload = function(e) {
    progress.style.width = '100%';
    progress.textContent = '100%';
    setTimeout("document.getElementById('progress_bar').className='';", 2000);
  }
  reader.readAsBinaryString(evt.target.files[0]);
}
	
0%

参考

<Thank you!>