读取文件,我们刚开始接触的是通过 input 标签,实现起来像这样:
<body> <input type='file' onchange="fileChange(this)"/> <script> function fileChange(target){ // 得到第一个上传的文件对象 var file = target.files[0] var fileInfo = '文件名:'+file.name+'类型:'+file.type+'文件字节大小:'+file.size+'上次修改时间:'+file.lastModifiedDate console.log(fileInfo) } </script></body>
复制代码
现如今 File API 提供了一种更安全访问客户端文件的方式,甚至可以通过 FileReader 读取文件中的数据。
FileReader
FileReader 是一种异步文件读取机制。
它有如下方法:
readAsText(file,encoding):以纯文本的形式读取文件
readAsDataURL(file):读取文件并将文件以数据 URI 的格式保存到 result
readAsBinaryString(file):读取文件并将一个字符串保存在 result 属性中,字符串中的每个字符表示一字节
readAsArrayBuffer(file):读取文件并将一个包含文件内容的 ArrayBuffer 保存到 result 属性中
它有如下事件:
progress:表示又读取了数据,50ms 左右触发一次
error:发生了错误触发
load:已经读完了整个文件触发
abort:中断读取过程
loadend:整个过程结束,load、error、abort 事件触发后触发的事件
看个例子:
<body> <input type='file' onchange="fileChange(this)"/> <div id='output' /> <script> function fileChange(target){ // 得到第一个上传的文件对象 var file = target.files[0], output = document.getElementById('output'), type = '', reader = new FileReader(); if(/image/.test(file.type)){ type = 'image' reader.readerAsDataURL(file) }else{ type = 'text' reader.readAsText(file) } // 文件读取进度 reader.onprogress = function(e){ if(e.lengthComputable){ console.log('当前读取进度为':e.loaded+'/'+e.total) } } // 文件读取错误 reader.onerror = function(){ // 1: 未找到文件 2:安全性错误 3:读取中断 4:文件不可读 5:编码错误 var errCode = reader.error.code } // 文件读取完成 reader.onload = function(){ // reader.result: 读取的文件 var html = type==='image'?`<img src='${reader.result}'>`:reader.result output.innerHtml = html } // 整个流程结束 reader.onloadend = function(){} } </script></body>
复制代码
读取部分文件
File 对象支持一个 slice()方法,接收两个参数:起始字节及要读取的字节数。返回一个 Blob 的实例,Blob 是 File 类型的父类型。
示例伪代码:
// 截取内容不同浏览器上的兼容方法function blobSlice(blob,start,length){ if(blob.slice){ return blob.slice(start,length) }else if(blob.webkitSlice){ return blob.webkitSlice(start,length) }else if(blob.mozSlice){ return blob.mozSlice(start,length) }else{ return null }}
// 伪代码,只展示核心var reader = new FileReader()var file = target.files[0]// 读取32字节内容var blob = blobSlice(file,0,32)reader.readAsText(blob)
复制代码
对象 URL
对象 URL 也被称为 blob URL,指的是引用保存在 File 或 Blob 中数据的 URL。好处是不必把文件内容读取到 JavaScript 中而直接使用文件内容。当然没使用的时候要释放 URL 占用的空间。
示例伪代码如下:
// 创建URL对象function createObjectUrl(blob){ if(window.URL){ return window.URL.createObjectURL(blob) }else if(window.webkitURL){ return window.webkitURL.createObjectURL(blob) }else{ return }}
// 销毁URL对象function revokeObjectURL(url){ if(window.URL){ window.URL.revokeObjectURL(url) }else if(window.webkitURL){ window.webkitURL.revokeObjectURL(url) }}
// 假设为图片文件对象var file = target.files[0]// 创建图片URL对象var url = createObjectUrl(file)var html = `<img src="${url}"/>`// 销毁URL对象revokeObjectURL(url)
复制代码
拖拽文件上传
结合 H5 拖放 API 和文件 API,能够创造出令人瞩目的用户界面。这里基本流程代码:
var oBox = document.getElementById('box'); var oM = document.getElementById('m1'); var timer = null; document.ondragover = function(){ console.log('文件来了') }; //进入子集的时候 会触发ondragover 频繁触发 不给ondrop机会 oBox.ondragenter = function(){ oBox.innerHTML = '请释放鼠标'; }; oBox.ondragover = function(){ return false; }; oBox.ondragleave = function(){ oBox.innerHTML = '请将文件拖拽到此区域'; }; oBox.ondrop = function(ev){ var file = ev.dataTransfer.files[0]; var reader = new FileReader(); //读取成功 reader.onload = function(){ console.log(reader); // 此处进行文件上传 var form = new FormData() form.append('file',file) ... // 其他代码略 }; reader.onloadstart = function(){ console.log('读取开始'); }; reader.onloadend = function(){ console.log('读取结束'); }; reader.onabort = function(){ console.log('中断'); }; reader.onerror = function(){ console.log('读取失败'); }; reader.onprogress = function(e){ console.log('当前读取进度为':e.loaded+'/'+e.total) }; };
复制代码
总结
至此我们学了 File API 相关知识。
评论