本文详细解析 JavaScript File API 的核心用法,涵盖通过 input 元素选择文件、获取 File 对象以及使用 FileReader 读取文件内容。文章重点介绍了 readAsText 与 readAsArrayBuffer 的区别,并通过 Promise 封装优化异步处理逻辑,最后提供二进制文件查看器的完整示例,帮助开发者掌握前端文件读取的最佳实践。
您可以利用 JavaScript File API 加载用户选定的文件内容。本节将深入介绍 File API 的基础使用方法。
接下来,我们将具体演示如何运用 File API 进行文件操作。
使用 JavaScript 读取文件概述
选择带有输入元素的文件
在 HTML 中,只需将 input 元素的 type 属性设置为 file,即可实现文件选择功能。
<input type="file">若需允许用户一次选择多个文件,请设置 multiple 属性。
<input type="file" multiple>当用户完成文件选择后,将触发一个 change 事件。
处理输入元素的变化事件
要捕获 change 事件,首先可以通过直接编写处理程序的方式实现。您可以将处理程序传递给 onchange 属性,从而在事件发生时直接访问输入元素,示例如下:
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>File Input Test</title>
<script>
function fileChanged(input) {
console.log(input);
for (let i = 0; i < input.files.length; i++) {
console.log(input.files[i]);
}
}
</script>
</head>
<body>
<input type="file" onchange="fileChanged(this)" multiple/>
</body>
</html>此外,您也可以通过动态获取输入元素的方式来处理 change 事件。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>File Input Test</title>
<script>
window.addEventListener('load', () => {
const f = document.getElementById('file1');
f.addEventListener('change', evt => {
const input = evt.target;
for (let i = 0; i < input.files.length; i++) {
console.log(input.files[i]);
}
});
});
</script>
</head>
<body>
<input type="file" id="file1" multiple/>
</body>
</html>在此场景下,输入元素会被作为事件对象 target 属性的一部分传递过来。
从输入元素的 files 属性中获取一个 File 对象
当 change 事件触发时,输入元素的 files 属性会返回一个 File 对象,该对象代表了用户所选的文件。
如果用户打开文件选择对话框但未选择任何文件便点击取消按钮,change 事件处理程序仍会被调用,但此时 files 属性将是一个长度为 0 的数组。
您可以将获取到的 File 对象存储起来,以便后续使用。
使用 FileReader 读取 File 对象
您可以使用 FileReader 对象来读取 File 对象的内容。只需将 File 对象传递给 FileReader 对象的 read 方法,即可开始读取操作。
读取文件的方法主要有以下几种:
- readAsText()
- readAsArrayBuffer()
- readAsBinaryString()
- readAsDataURL()
FileReader 对象用于读取 Blob 中的数据。由于 File 对象是从 Blob 派生而来的,因此它同样适用于 FileReader 的读取操作。
当 FileReader 对象成功加载文件时,会触发 onload 事件。读取结果会被设置在 FileReader 对象的 result 属性中。
调用 readAsText() 后,result 属性中会包含字符串;而调用 readAsArrayBuffer() 后,result 属性中将设置为 ArrayBuffer 对象。
接下来,让我们通过实际示例来演示如何读取文件。
读取文件示例
读取和显示所选文件的示例
在此,我们将构建一个具备以下功能的示例:

当用户选择文件后,系统将显示所选文件的内容。
以下展示了在此操作中使用的 HTML 文件和样式表内容。
HTML 文件代码如下,请将其保存为 file1.html。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>File API 1</title>
<script src="file1.js"></script>
<link href="style.css" rel="external nofollow" rel="stylesheet" />
</head>
<body>
<input type="file" id="file1" />
<pre id="pre1"></pre>
</body>
</html>其中,input 元素的 type 属性设置为 file,并设置了 id 为 file1。
样式表 style.css 代码如下。此处仅对字体进行了微调并添加了背景颜色,未做过多复杂设计。
@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap');
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap');
html {
font-family: 'Roboto', sans-serif;
}
pre {
font-family: 'Roboto mono', monospace;
font-size: 0.9rem;
background-color: #D6EAF8;
padding: 10px;
}JavaScript 文件 file1.js 代码如下。
window.addEventListener('load', () => {
const f = document.getElementById('file1');
f.addEventListener('change', evt => {
let input = evt.target;
if (input.files.length == 0) {
console.log('No file selected');
return;
}
const file = input.files[0];
const reader = new FileReader();
reader.onload = () => {
const pre = document.getElementById('pre1');
pre.innerHTML = reader.result;
};
reader.readAsText(file);
});
});在 window 对象的 load 事件处理程序中,为该文件输入元素设置了 change 事件处理程序。
当用户执行文件选择操作时,将触发此 change 事件处理程序。
Event 对象会被传递给事件处理程序。执行文件选择操作的输入元素会被赋值给事件对象的 target 属性。该输入元素的 files 属性将设置为所选文件对象的列表。
本次示例中未在 input 元素上设置 multiple 属性,因此 files 属性中将仅包含一个 File 对象。
获取到 File 对象后,接下来的步骤便是读取文件内容。
const file = input.files[0];
const reader = new FileReader();
reader.onload = () => {
const pre = document.getElementById('pre1');
pre.innerHTML = reader.result;
};
reader.readAsText(file); 这样,预读的文件内容将被设置到元素中显示。
Promise 的事件处理和使用
在上述代码中,文件阅读器对象的 readAsText() 方法在调用之前,我已经设置了事件处理程序。
文件阅读器还提供了其他可用事件,但每次设置这些事件后再调用可能会略显复杂。
因此,让我们使用 Promise 来整理我们的代码结构。
准备一个接收 File 对象的函数,定义如下:
const readAsTextReader = file => {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onloadstart = ev => {
console.log(`onloadstart: total=${ev.loaded}/${ev.loaded}`);
};
reader.onloadend = ev => {
console.log(`onloadend: total=${ev.loaded}/${ev.loaded}`);
};
reader.onprogress = ev => {
console.log(`onprogress: total=${ev.loaded}/${ev.loaded}`);
};
reader.onerror = () => {
reader.abort();
reject('Unknown error occurred during reading the file');
};
reader.onload = () => {
console.log('onload');
resolve(reader.result);
};
reader.readAsText(file);
});
};这样,读取文件时的异步处理即可利用 Promise 的 then 和 catch 方法,应用方式如下。
window.addEventListener('load', () => {
const f = document.getElementById('file1');
f.addEventListener('change', evt => {
const input = evt.target;
if (input.files.length == 0) {
return;
}
const file = input.files[0];
console.log(file);
readAsTextReader(file)
.then(value => {
const pre = document.getElementById('pre1');
pre.innerHTML = value;
})
.catch(reason => {
alert(reason);
});
});
});简单的二进制文件查看器
接下来,让我们创建一个简单的二进制文件查看器作为示例,该示例不仅能读取文本文件,还能处理二进制文件。

选择文件并使用 FileReader 读取文件的位置与前述步骤相同。
然而,这一次我们使用 readAsArrayBuffer() 来读取文件。结果将以 ArrayBuffer 形式返回。
ArrayBuffer 是 JavaScript 中的字节字符串。有关详细信息,请参阅“使用 ArrayBuffer 处理二进制数据”。
const readAsArrayBufferReader = file => {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onerror = () => {
reader.abort();
reject('Unknown error occurred during reading the file');
};
reader.onload = () => {
console.log('onload');
resolve(reader.result);
};
reader.readAsArrayBuffer(file);
});
};
window.addEventListener('load', () => {
const f = document.getElementById('file1');
f.addEventListener('change', evt => {
const input = evt.target;
if (input.files.length == 0) {
return;
}
let file = input.files[0];
console.log(file);
if (!file) {
return;
}
if (file.size > 50 * 1024) {
alert('Please select a file smaller than 50kb.');
return;
}
readAsArrayBufferReader(file)
.then(buff => {
console.log(buff);
let s = '';
let a = new Uint8Array(buff);
for (let i = 0; i * 16 < a.length; i++) {
let line = '';
let p = i * 16;
let b = a.slice(p, Math.min(a.length, p + 16));
for (const e of b) {
let h = e
.toString(16)
.toUpperCase()
.padStart(2, '0');
line += ' ' + h;
}
let addr = p
.toString(16)
.toUpperCase()
.padStart(8, '0');
line = `${addr}:${line}\n`;
s += line;
}
let pre = document.getElementById('pre1');
pre.innerHTML = s;
})
.catch(reason => {
alert(reason);
});
});
});本次示例中文件大小限制为 50KB。
从读取为 ArrayBuffer 的数据创建一个 Uint8Array 对象。随后利用 slice() 方法,以 16 字节为增量进行格式化显示。
至此,我们已经介绍了如何在 JavaScript 中使用 File 对象和 FileReader 读取文件,如何利用 Promise 简化异步处理,以及处理二进制数据的示例。
到此这篇关于如何使用 JavaScript 读取文件的文章就介绍到这了,更多相关 js 读取文件内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!