- File API
- FileReader API
- Filesystem & FileWriter API
- Blob constructing
- Blob URLs
- Example
- 扩展阅读
规范提供的从local filesystem 访问文件的几个接口:
方法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 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包含四种异步读取文件的方式:
一旦这些read方法被调用,onloadstart, onprogress, onload, onabort, onerror, onloadend就可以被用来追踪进度。
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); } }
File接口提供了slice方法支持把文件切成不同的片段,第一个参数是起始的字节数,第二个参数是结束的字节数,还有一个可选的内容类型字符串可以作为第三个参数:
var blob = file.slice(startingByte, endingByte); reader.readAsBinary(blob);
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); }
可以使用onloadstart和onprogress事件来监视读取进度
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]); }