1. 简介
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
其中 File 对象可以是来自用户在一个 < input > 元素上选择文件后返回的 FileList 对象,也可以来自拖放操作生成的 DataTransfer 对象,还可以是来自在一个 HTMLCanvasElement 上执行 mozGetAsFile() 方法后返回结果。
重要提示: FileReader 仅用于以安全的方式从用户(远程)系统读取文件内容,不能用于从文件系统中按路径名简单地读取文件。 要在JavaScript中按路径名读取文件,应使用标准 Ajax 解决方案进行服务器端文件读取。如果读取跨域,则使用 CORS 权限。
属性
方法
FileReader 的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。
下面的表格列出了这些方法以及他们的参数和功能,
需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result属性中。
事件处理
FileReader 包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。
因为 FileReader 继承自 EventTarget,所以所有这些事件也可以通过 addEventListener 方法使用。
检测浏览器对 FileReader 的支持
if(window.FileReader) { var fr = new FileReader(); // add your code here }else { alert("Not supported by your browser!"); }
2. FileReader 对象的使用
2.1 基本使用
准备文件
完整代码:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="format-detection" content="telephone=no"> <title>test</title> </head> <body> <div> <input type="file"> <input type="file" id="imgFile"> <img src="" id="preview"> </div> <script type="text/javascript"> let inputFile = document.querySelector('input[type=file]'); inputFile.onchange = function(){ var reader = new FileReader() // result 属性中将包含一个字符串以表示所读取的文件内容。 reader.readAsText(this.files[0]) reader.onload = function(){ console.log(this.result) } } let imgFile = document.querySelector('#imgFile'); let priview = document.querySelector("#preview"); imgFile.onchange = function () { var reader = new FileReader(); // result 属性中将包含一个 data: URL 格式的 Base64 字符串以表示所读取文件的内容 reader.readAsDataURL(this.files[0]) reader.onload = function () { priview.src = reader.result; console.log(this.result) } } </script> </body> </html>
效果:
2.2 事件处理
完整代码:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="format-detection" content="telephone=no"> <title>test</title> </head> <body> <div> <input type="file"> </div> <script type="text/javascript"> let inputFile = document.querySelector('input[type=file]'); inputFile.onchange = function(){ var reader = new FileReader() // result 属性中将包含一个字符串以表示所读取的文件内容。 reader.readAsText(this.files[0]) reader.onloadstart = function(){ console.log("onloadstart状态"+this.readyState) } reader.onloadend= function(){ console.log("onloadend状态"+this.readyState) } reader.onprogress = function(){ console.log("onprogress状态"+this.readyState) } reader.onload = function(){ console.log("onload状态"+this.readyState,"获取的数据:"+this.result); } reader.onerror = function(){ console.log('出错了') } reader.onerror = function(){ console.log('处理abort事件。该事件在读取操作被中断时触发。') } } </script> </body> </html>
效果:
分析:
onloadstart 状态:数据正在被加载;
onloadend 状态:已完成全部的读取请求;
.当然状态为 0(readyState)表示还没有加载任何数据;
每过50ms左右,就会触发一次 progress 事件;也就是说这个可能多次触发,onload 事件在 onloadend 之前触发;
由于种种原因无法读取文件时,会触发 error 事件。触发 error 事件时,相关信息保存在 FileReader 对象的 error 属性中,这个属性将保存一个对象,此对象只有一个属性 code,即错误码。1 表示未找到文件,2 表示安全性错误,3 表示读取中断,4 表示文件不可读,5 表示编码错误;
如果想中断读取过程,可调用 abort 方法,就会触发 abort 事件。在返回时,readyState 属性为 DONE。一般用于后台的操作;
2.3 node操作文件
根据以上可知,浏览器中的 JavaScript 是没有文件操作的能力的(基于安全,不能直接操作本地文件),但是 Node 中的 JavaScript 具有文件操作的能力。
读取文件
// 1. 使用 require 方法加载 fs 核心模块 var fs = require('fs') // 2. 读取文件 // 第一个参数就是要读取的文件路径 // 第二个参数是一个回调函数 // 成功 // data 数据 // error null // 失败 // data undefined没有数据 // error 错误对象 fs.readFile('read.txt', function (error, data) { // 在这里就可以通过判断 error 来确认是否有错误发生 if (error) { console.log('读取文件失败了') } else { console.log(data.toString()) } })
文件读取是异步操作
当我们读取多个文件,发现使用 readfile 读取文件并不能一定按顺序打印结果,所以这是一个异步操作,如何顺序读取文件。
使用 Promise
var fs = require('fs') function pReadFile(filePath) { return new Promise(function (resolve, reject) { fs.readFile(filePath, 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) } pReadFile('./data/a.txt') .then(function (data) { console.log(data) return pReadFile('./data/b.txt') }) .then(function (data) { console.log(data) return pReadFile('./data/c.txt') }) .then(function (data) { console.log(data) })
文件写入
fs.writeFile('read.txt', '大家好,给大家介绍一下,我是文件写入', function (error) { if (error) { console.log('写入失败') } else { console.log('写入成功了') } })