FileReader
[TOC]
索引
属性:
- reader.result:
string|ArrayBuffer|null
,只读,访问读取结果。 - reader.error:
DOMException|null
,用于获取文件读取过程中发生的错误信息。 - reader.readyState:
0|1|2
,只读,获取当前读取状态。
方法:
- new FileReader():
()
,构造函数,创建一个新的 FileReader 实例。 - reader.readAsText():
(file,encoding?)
,以文本形式异步读取文件内容。 - reader.readAsDataURL():
(file)
,将文件内容转换为 Base64 编码的 Data URL,可直接用于嵌入网页(如图片预览)。 - reader.readAsArrayBuffer():
(file)
,将文件内容读取为ArrayBuffer
对象(二进制数据的底层容器),用于直接操作二进制数据。 - reader.abort():
()
,立即中止正在进行的文件读取操作。
事件:
load:
event
,读取成功完成时触发。error:
event
,当读取由于错误而失败时触发。abort:
event
,当读取被中止时触发,例如因为程序调用了FileReader.abort()
方法。progress:
event
,读取数据时持续触发。loadend:
event
,读取完成时触发,无论成功与否。loadstart:
event
,读取开始时触发。
FileReader
属性
result
reader.result:string|ArrayBuffer|null
,只读,访问读取结果。
返回:
result:
string|ArrayBuffer|null
,具体返回类型取决于调用的读取方法:string
:调用 readAsText() 或 readAsDataURL() 返回的类型。ArrayBuffer
:调用 readAsArrayBuffer() 返回的类型。null
:未调用读取方法或读取失败返回的类型。
语法特性:
异步获取结果:
result
仅在读取操作完成后(触发onload
事件)才包含有效值。- 在
onload
事件外直接访问result
可能得到null
。
jsconst reader = new FileReader(); reader.onload = function(e) { console.log(e.target.result); // 正确:在 onload 中获取结果 }; reader.readAsText(file); console.log(reader.result); // 错误:此时尚未完成读取,结果为 null
读取状态依赖:
- 若读取过程中调用
abort()
或发生错误(触发onerror
),result
为null
。 - 可通过
readyState
判断当前状态:0
(未开始)、1
(读取中)、2
(完成)。
- 若读取过程中调用
二进制数据处理:
ArrayBuffer
需转换为具体类型(如Uint8Array
)才能操作:jsreader.onload = function(e) { const buffer = e.target.result; const uint8Array = new Uint8Array(buffer); console.log(uint8Array); }; reader.readAsArrayBuffer(file);
error
reader.error:DOMException|null
,用于获取文件读取过程中发生的错误信息。
返回:
error:
DOMException|null
,返回值类型和含义如下:DOMException
:{name,message}
,读取过程中发生错误。null
:读取成功或未发生错误。
语法特性:
错误类型(DOMException.name):
错误类型 触发场景 NotFoundError
文件未找到(如用户取消选择文件后尝试读取)。 SecurityError
文件被浏览器标记为不安全(如跨域文件未经允许)。 AbortError
读取操作被 abort()
方法中止。NotReadableError
文件无法读取(如文件损坏或权限问题)。 EncodingError
编码错误(如 readAsText()
指定了不支持的编码格式)。错误处理必要性:必须监听
onerror
事件以捕获潜在错误,否则用户可能无法感知读取失败:jsreader.onerror = function(e) { alert(`读取失败: ${e.target.error.message}`); };
异步错误捕获:错误信息仅在触发
onerror
事件后有效。在事件外直接访问error
可能为null
。jsreader.readAsText(file); console.log(reader.error); // ❌ 此时可能尚未触发错误,结果为 null
状态关联性:错误发生后,
readyState
变为2
(DONE
)。错误重置:每次调用新的读取方法(如
readAsText()
)时,error
会被重置为null
。
示例:
监听错误事件并获取错误信息:
jsconst reader = new FileReader(); reader.onerror = function(e) { const error = reader.error; // 或 e.target.error console.error("错误类型:", error.name); // 错误类型: NotReadableError console.error("错误描述:", error.message); // 错误描述: The file could not be read. }; reader.readAsText(file); // 假设此操作因文件问题失败
readyState
reader.readyState:0|1|2
,只读,获取当前读取状态。
返回:
state:
0|1|2
,默认:0
,返回当前读取操作的状态。0
:常量名:EMPTY
,未开始读取。此时尚未调用任何读取方法,或读取已被重置。1
:常量名:LOADING
,数据正在加载中。读取操作已开始但未完成(如onprogress
事件触发期间)。2
:常量名:DONE
,读取操作已完成(无论成功、失败或中止)。此时可通过result
或error
获取结果。
语法特性:
- 状态流转:
- 初始状态:创建
FileReader
实例时,readyState
默认为0
(EMPTY
)。 - 读取开始:调用
readAsText()
、readAsDataURL()
等方法后,状态变为1
(LOADING
)。 - 读取结束:操作完成(成功、失败或中止)后,状态变为
2
(DONE
)。
- 初始状态:创建
- 与事件的关系:
onloadstart
:当状态从0
→1
时触发。onprogress
:当状态为1
时周期性触发。onload
/onerror
/onabort
:当状态从1
→2
时触发。onloadend
:无论成功与否,状态变为2
后触发。
- 状态不可逆:一旦进入
DONE
状态,readyState
不会自动重置为EMPTY
。需重新创建FileReader
实例以进行新的读取。
示例:
监听状态变化:
jsconst reader = new FileReader(); // 初始状态为 0 // 监听状态变化(通过事件间接判断) reader.onloadstart = function(e) { console.log("状态: LOADING (1)"); }; reader.onload = function(e) { console.log("状态: DONE (2)"); console.log("结果:", e.target.result); }; reader.readAsText(file); // 触发状态变化 0 → 1
判断是否可安全操作:
jsif (reader.readyState === 1) { console.log("读取正在进行,不可调用新操作"); } else { reader.readAsDataURL(newFile); // 安全调用新读取 }
方法
new FileReader()
new FileReader():()
,构造函数,创建一个新的 FileReader 实例。
返回:
reader:
FileReader
,返回一个 FileReader 实例对象,用于后续文件读取操作。
语法特性:
同步操作:
- 每个
FileReader
实例同一时间只能处理一个读取操作。 - 若需要并发读取多个文件,需为每个文件创建独立的
FileReader
实例:
js// 并发读取多个文件 files.forEach(file => { const reader = new FileReader(); // 每个文件单独实例 reader.onload = (e) => { /* 处理结果 */ }; reader.readAsText(file); });
- 每个
内存管理:读取大文件(如视频)时,
result
属性会占用较大内存,操作完成后建议手动释放引用:jsreader.onload = function(e) { const data = e.target.result; // 处理数据... reader.result = null; // 释放内存(可选) };
错误处理:必须监听
onerror
事件以捕获可能的读取失败:jsreader.onerror = function(e) { console.error("错误类型:", e.target.error.name); console.error("错误信息:", e.target.error.message); };
示例:
基本用法:
js// 1. 创建 FileReader 实例 const reader = new FileReader(); // 2. 监听加载完成事件 reader.onload = function(e) { console.log("读取结果:", e.target.result); }; // 3. 选择文件并读取(例如通过 <input type="file">) const fileInput = document.querySelector('input[type="file"]'); fileInput.addEventListener('change', function(e) { const file = e.target.files[0]; reader.readAsText(file); // 以文本形式读取文件 });
readAsText()
reader.readAsText():(file,encoding?)
,以文本形式异步读取文件内容。
file:
File|Blob
,要读取的文件对象(通常通过<input type="file">
或拖放操作获取)。encoding?:
string
,默认:UTF-8
,指定文本编码格式。返回:
result:
undefined
,异步方法,没有直接返回值。读取结果通过FileReader
的onload
事件获取(存储在result
属性中)。
语法特性:
结果获取:
成功读取:通过
onload
事件监听器访问result
(类型为string
):jsconst reader = new FileReader(); reader.onload = function(e) { const textContent = e.target.result; // 字符串形式的文件内容 console.log(textContent); }; reader.readAsText(file); // 触发读取操作
失败处理:通过
onerror
监听错误:jsreader.onerror = function(e) { console.error("读取失败:", e.target.error); };
编码支持:默认使用
UTF-8
编码,但支持其他常见编码(如"ASCII"
、"ISO-8859-1"
)(Safari 对非 UTF-8 编码的支持有限)。异步操作:
读取过程非阻塞,需通过事件监听获取结果。
可通过
onprogress
监听读取进度:jsreader.onprogress = function(e) { const percent = (e.loaded / e.total) * 100; console.log(`已读取: ${percent.toFixed(2)}%`); };
中断读取:调用
abort()
可终止读取:jsreader.abort(); // 中断后触发 onabort 事件
文件类型限制:
- 适用于文本文件(
.txt
,.csv
,.json
等),读取二进制文件(如图片)可能得到乱码。 - 二进制文件建议使用
readAsArrayBuffer()
或readAsDataURL()
。
- 适用于文本文件(
大文件处理:超大文本文件可能导致内存压力,需结合
onprogress
分阶段处理。
示例:
读取文本文件:
html<input type="file" id="fileInput"> <script> document.getElementById("fileInput").addEventListener("change", function(e) { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = function(e) { console.log("文件内容:", e.target.result); }; reader.readAsText(file); // 默认 UTF-8 编码 }); </script>
指定编码读取:
jsreader.readAsText(file, "ISO-8859-1"); // 使用 Latin-1 编码
readAsDataURL()
reader.readAsDataURL():(file)
,将文件内容转换为 Base64 编码的 Data URL,可直接用于嵌入网页(如图片预览)。
file:
File|Blob
,要读取的文件对象(通过<input type="file">
或拖放操作获取的文件)。返回:
result:
undefined
,异步方法,没有直接返回值。读取结果通过FileReader
的onload
事件获取(存储在result
属性中)。
语法特性:
结果获取:
读取成功:通过
onload
事件监听器访问result
(类型为string
,格式为 Data URL)。jsconst reader = new FileReader(); reader.onload = function(e) { const dataURL = e.target.result; // 示例:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." console.log(dataURL); }; reader.readAsDataURL(file); // 触发读取操作
失败处理:通过
onerror
监听错误:jsreader.onerror = function(e) { console.error("读取失败:", e.target.error); };
Data URL 格式:
- 格式:
data:[<mediatype>][;base64],<data>
。mediatype
:文件的 MIME 类型(如image/png
、text/plain
)。base64
:标识数据采用 Base64 编码。data
:文件内容的 Base64 字符串。
- 示例:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
- 格式:
适用场景:
图片预览:直接作为
<img>
或<canvas>
的src
:jsreader.onload = function(e) { document.getElementById("preview").src = e.target.result; };
文件内容嵌入网页(如 PDF 预览、音频播放)。
异步操作:
读取过程非阻塞,需通过事件监听获取结果。
可通过
onprogress
监听读取进度:jsreader.onprogress = function(e) { const percent = (e.loaded / e.total) * 100; console.log(`已读取: ${percent.toFixed(2)}%`); };
中断读取:调用
abort()
可终止读取:jsreader.abort(); // 中断后触发 onabort 事件
文件大小限制:Data URL 是文件的 Base64 编码,体积比原始文件大 约 33%。大文件谨慎使用。
安全性:Base64 编码的 Data URL 可能被恶意利用(如 XSS 攻击),需避免处理不可信来源的文件。
内存释放:读取完成后,可手动释放
result
属性以节省内存:jsreader.onload = function(e) { const dataURL = e.target.result; // 使用数据... reader.result = null; // 释放内存(可选) };
示例:
读取图片预览:
js<input type="file" id="fileInput"> <img id="preview" src="" alt="预览"> <script> document.getElementById("fileInput").addEventListener("change", function(e) { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = function(e) { document.getElementById("preview").src = e.target.result; }; reader.readAsDataURL(file); // 转换为 Data URL }); </script>
读取文本文件:
js// 读取 .txt 文件,Data URL 的 mediatype 为 "text/plain" reader.readAsDataURL(file);
readAsArrayBuffer()
reader.readAsArrayBuffer():(file)
,将文件内容读取为 ArrayBuffer
对象(二进制数据的底层容器),用于直接操作二进制数据。
file:
File|Blob
,要读取的文件对象(通过<input type="file">
或拖放操作获取的文件)。返回:
result:
undefined
,异步方法,没有直接返回值。读取结果通过FileReader
的onload
事件获取(存储在result
属性中)。
语法特性:
结果获取:
成功读取后,通过
onload
事件监听器访问result
(类型为ArrayBuffer
):jsconst reader = new FileReader(); reader.onload = function(e) { const arrayBuffer = e.target.result; // ArrayBuffer 对象 console.log(arrayBuffer); }; reader.readAsArrayBuffer(file); // 触发读取操作
失败处理:通过
onerror
监听错误:jsreader.onerror = function(e) { console.error("读取失败:", e.target.error); };
二进制数据操作:
ArrayBuffer
是固定长度的二进制数据容器,需通过TypedArray
(如Uint8Array
)或DataView
操作具体数据:jsreader.onload = function(e) { const buffer = e.target.result; const uint8Array = new Uint8Array(buffer); // 转换为 Uint8Array console.log("二进制数据:", uint8Array); };
适用场景:
- 图像处理(如像素级操作)。
- 文件分片上传(如大文件切割后逐块上传)。
- 加密/解密二进制数据。
- 解析自定义二进制格式(如
.zip
、.png
等)。
异步操作:同 readAsDataURL / readAsText。
中断读取:同 readAsDataURL / readAsText。
文件大小限制:
ArrayBuffer
直接存储文件原始二进制数据,大文件可能占用大量内存,需合理分片处理。内存释放:读取完成后,可手动释放
result
属性以节省内存:jsreader.onload = function(e) { const buffer = e.target.result; // 处理数据... reader.result = null; // 释放内存(可选) };
示例:
读取图片并转换为二进制数组:
html<input type="file" id="fileInput"> <script> document.getElementById("fileInput").addEventListener("change", function(e) { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = function(e) { const buffer = e.target.result; const uint8Array = new Uint8Array(buffer); console.log("二进制数据:", uint8Array); }; reader.readAsArrayBuffer(file); }); </script>
分片上传伪代码:
jsconst chunkSize = 1024 * 1024; // 1MB 分片 let offset = 0; function uploadNextChunk(file) { const chunk = file.slice(offset, offset + chunkSize); const reader = new FileReader(); reader.onload = function(e) { const buffer = e.target.result; // 将 buffer 上传到服务器 fetch("/upload", { method: "POST", body: buffer }); offset += chunkSize; if (offset < file.size) uploadNextChunk(file); }; reader.readAsArrayBuffer(chunk); } uploadNextChunk(largeFile);
abort()
reader.abort():()
,立即中止正在进行的文件读取操作。
返回:
result:
undefined
,没有返回值,但调用后会触发onabort
事件,并将readyState
设为2
(DONE
)。
语法特性:
中止行为:
- 中止后,
FileReader
的result
属性被重置为null
。 - 若读取操作尚未开始(
readyState
为0
),调用abort()
无效。 - 若读取已开始但未完成(
readyState
为1
),中止操作并触发onabort
事件,并将readyState
设为2
。
- 中止后,
事件触发:调用
abort()
后,会依次触发以下事件:onabort
:表示读取操作被中止。onloadend
:表示读取流程结束(无论成功、失败或中止)。
状态管理:
调用
abort()
后,FileReader
实例的readyState
变为2
(DONE
),无法继续使用该实例进行新操作。需重新创建
FileReader
实例以进行新的读取:jsreader.abort(); reader = new FileReader(); // 重新实例化 reader.readAsText(file); // 重新读取
错误处理:中止操作不会触发
onerror
事件,但若中止时发生错误(如文件损坏),仍需监听onerror
:jsreader.onerror = function(e) { console.error("错误:", e.target.error); };
应用场景:
- 用户主动取消:提供“取消”按钮,允许用户中止耗时的大文件读取。
- 超时中断:设置读取超时,超时后自动中止操作。
- 内存优化:在读取大文件时,若检测到内存不足,主动中止以避免崩溃。
示例:
基础用法:
jsconst reader = new FileReader(); // 开始读取操作 reader.readAsText(file); // 中途中止 setTimeout(() => { reader.abort(); // 中止读取 }, 1000); // 假设 1 秒后中止 // 监听中止事件 reader.onabort = function(e) { console.log("读取操作已中止"); }; // 监听结束事件 reader.onloadend = function(e) { console.log("读取流程结束"); };
结合用户交互(如取消按钮):
html<input type="file" id="fileInput"> <button id="cancelBtn">取消读取</button> <script> let reader; document.getElementById("fileInput").addEventListener("change", function(e) { const file = e.target.files[0]; reader = new FileReader(); reader.onload = function(e) { console.log("读取结果:", e.target.result); }; reader.onabort = function(e) { console.log("用户取消了读取"); }; reader.readAsText(file); }); // 点击按钮中止读取 document.getElementById("cancelBtn").addEventListener("click", function() { if (reader && reader.readyState === 1) { reader.abort(); } }); </script>
事件
load:
event
,读取成功完成时触发。error:
event
,当读取由于错误而失败时触发。abort:
event
,当读取被中止时触发,例如因为程序调用了FileReader.abort()
方法。progress:
event
,读取数据时持续触发。loadend:
event
,读取完成时触发,无论成功与否。loadstart:
event
,读取开始时触发。