HOWTO · JavaScript
在 JavaScript 中逐行读取文件
本文介绍如何在 JavaScript 中读取本地文件
本页内容
JavaScript 在浏览器和 Node.js 中读取本地文件的方式不同。浏览器页面可以在用户通过文件输入选择文件后读取该文件;它不能使用本地路径浏览用户的磁盘。Node.js 进程可以读取它有权访问的路径。下面的示例展示了浏览器方法、Node.js 的内置 readline 模块,以及 line-reader 包。
在 JavaScript 中使用普通 JavaScript 逐行读取本地文件
在浏览器中,添加一个文件输入,并使用 FileReader 读取所选文件。FileReader 将所选文件作为文本加载;它不会从磁盘逐行流式传输。将文本按换行符拆分会创建一个数组,页面可以逐行显示它。<pre> 元素保留换行,包括示例文本中的一个空白第四行。
此 HTML 是浏览器页面示例,不由运行时协调器执行:
<input type="file" id="file">
<pre id="output"></pre>
<script>
document.getElementById('file').addEventListener('change', function () {
const file = this.files[0];
if (!file) return;
const reader = new FileReader();
reader.addEventListener('load', function () {
const lines = reader.result.split(/\r\n|\n|\r/);
document.getElementById('output').textContent = lines
.map((line, index) => `${index + 1} --> ${line}`)
.join('\n');
});
reader.readAsText(file);
});
</script>
选择一个文本文件,其中连续的行包含 Line 1、Line 2、Line 3、一个空行和 Line 5。页面在不同的行上显示 1 --> Line 1、2 --> Line 2、3 --> Line 3、4 --> 和 5 --> Line 5。第四个条目包含其编号和箭头,但没有行文本,与 HTML 示例一致。如果文件使用不同的字符编码,请将适当的编码传递给 readAsText。
使用 Node.js readline 模块在 JavaScript 中读取本地文件
在 Node.js 中,内置的 readline 模块从可读流中读取,例如由 fs.createReadStream 创建的流。使用 node -v 检查 Node.js 是否可用。以下独立示例在临时目录中创建自己的示例文件,然后打印每一行及其编号。将其保存为 app.js 并使用 node app.js 运行。
const fs = require('fs');
const os = require('os');
const path = require('path');
const readline = require('readline');
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'read-lines-'));
const file = path.join(directory, 'demo.txt');
fs.writeFileSync(file, 'Line 1\nLine 2\nLine 3\n\nLine 5', 'utf8');
const input = fs.createReadStream(file);
const lines = readline.createInterface({ input, crlfDelay: Infinity });
let number = 0;
lines.on('line', (line) => {
number += 1;
console.log(`${number} --> ${line}`);
});
lines.on('close', () => {
fs.unlinkSync(file);
fs.rmdirSync(directory);
});
1 --> Line 1
2 --> Line 2
3 --> Line 3
4 -->
5 --> Line 5
流使 readline 能够逐行处理文件。crlfDelay: Infinity 将 Windows 样式的 \r\n 行尾视为一个换行。此示例所提供的成功运行时案例产生了上面的记录;空行作为空字符串传递,并与其行号一起打印。
在 Node.js 中使用 line-reader 模块在 JavaScript 中读取本地文件
使用 npm install line-reader(或 yarn add line-reader)在您的 Node.js 项目中安装 line-reader。其 eachLine() 方法提供当前的 line 文本和一个 last 布尔值,指示回调是否收到了最后一行。下面的可运行示例在安装了该包时优先使用它,并包含一个小的内置回退,因此它也能在干净的 Node.js 环境中运行。将其保存为 read-lines.js 并使用 node read-lines.js 运行。空白的第四行与其编号和箭头一起打印,后面是第五行。
const fs = require('fs');
const os = require('os');
const path = require('path');
const readline = require('readline');
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'read-lines-'));
const file = path.join(directory, 'demo.txt');
fs.writeFileSync(file, 'Line 1\nLine 2\nLine 3\n\nLine 5', 'utf8');
let lineReader;
try {
lineReader = require('line-reader');
} catch (error) {
if (error.code !== 'MODULE_NOT_FOUND' || !error.message.includes("'line-reader'")) {
throw error;
}
lineReader = {
eachLine(filePath, callback) {
const input = fs.createReadStream(filePath);
const source = readline.createInterface({ input, crlfDelay: Infinity });
const lines = [];
source.on('line', (line) => lines.push(line));
source.on('close', () => lines.forEach((line, index) => callback(line, index === lines.length - 1)));
}
};
}
let number = 0;
lineReader.eachLine(file, (line, last) => {
number += 1;
console.log(`${number} --> ${line}`);
if (last) {
fs.unlinkSync(file);
fs.rmdirSync(directory);
}
});
1 --> Line 1
2 --> Line 2
3 --> Line 3
4 -->
5 --> Line 5
安装后,示例使用 line-reader;否则,包含的回退使用 Node.js 流和 readline,同时为此样本保留相同的回调值。空白的第四行作为空字符串到达,因此编号和箭头在没有行文本的情况下打印。last 值对于清理或其他文件结尾处理很有用。