javascript - 如何在 Vanilla JavaScript 中逐行读取文件?
问题描述
我有一个要阅读的文件(words.txt)。我想把它保存在一个数组中,但是文件中包含它太长了,所以我把它放在一个单独的文件中。我可以使用 URL 来获取它,但我也将文件放在与 javascript 文件相同的文件夹中。在不使用 jQuery 或 Node.js 的情况下,最简单的方法是什么?
解决方案
似乎您正在尝试分块读取一个非常大的文件,以免浏览器因内存过多而崩溃,对吗?如果没有,请告诉我。
虽然一般来说,要“逐行”阅读,人们(如何使用 Javascript 读取本地文本文件并逐行读取?)通常只是加载整个文件,然后将其拆分"\n"
,但这无法解决问题使用过大的文件使浏览器崩溃。
您正在寻找的是 FileReader 或 XMLHttpRequest 类的进度事件,具体取决于您是从服务器获取本地、用户选择的文件还是文件。
它应该允许您以块的形式读取较大文件的一部分。随着块的进入,您可以跟踪换行符 ( \n
),并相应地将每组文本保存在一个新数组中。
为了跟踪块,XMLHttpRequest 分块响应,只读取正在进行的最后一个响应,如果您可以在内存中保留累积的响应数据量,如果不是,您可以尝试如何编写 javascript中提到的数组缓冲区方法在客户端及时接收和解析“分块”响应?,甚至更好地使用答案中提到的 ReadableStream 类以及 fetch。
基于该答案以及其他答案,我试图组合一个函数,该函数将为您读取每一行的回调,并按块读取总 URL,即使块本身可能略多于 1 行一次,但这是我能想到的最接近客户端 JavaScript 的方法,如果它有效,请告诉我:
function readLineByLine(url, callback) {
fetch(url)
.then(response => {
let fetchReader = response.body.getReader(),
decoder = new TextDecoder(),
currentLineData = "",
totalLines = [];
fetchReader.read()
.then(function readData(progress) {
let thisJustInSomeData = decoder.decode(
progress.value || "",
{
stream: !progress.done
}
),
lines = thisJustInSomeData.split("\n");
if(lines.length < 2) {
currentLineData += lines[0];
} else {
lines.forEach((x, i, a) => {
currentLineData += x;
totalLines.push(currentLineData);
if(i < lines.length - 1) {
currentLineData = "";
}
});
}
totalLines.forEach(line => {
callback({line});
});
totalLines = []
if(progress.done) {
callback({done: progress.done})
return;
}
return readData();
})
});
}
然后调用它
readLineByLine("someURLorTxtFileWithLotsOfLines", line => console.log(line));
推荐阅读
- html - 如何将文本和未排序列表放在同一行
- python - kdims 如何为 geoviews 中的多边形工作?
- java - 如何更改 Recyclerview 所选项目的背景
- c++ - 动态分配内存
- javascript - 创建日期选择器时引导日期选择器设置日期
- c# - 我怎样才能随机化(不是随机播放)一个字符串?
- swift - ImagePicker 确认视图对齐
- javascript - 如何使用管道从复选框列表中过滤Angular 7中的对象数组
- laravel - 无法在 Bitnami LAMP 堆栈上使用 Cron 运行 PHP Artisan 命令
- angular - 以不同的角度分量显示数据