【问题标题】:How do I read a file line by line in Vanilla JavaScript? [duplicate]如何在 Vanilla JavaScript 中逐行读取文件? [复制]
【发布时间】:2020-09-05 06:20:33
【问题描述】:

我有一个想要阅读的文件(words.txt)。我想将它保存在一个数组中,但是包含在文件中太长了,所以我将它放在一个单独的文件中。我可以使用 URL 来获取它,但我也将文件放在与 javascript 文件相同的文件夹中。在不使用 jQuery 或 Node.js 的情况下,最简单的方法是什么?

【问题讨论】:

  • @AlonEitan 没有解释如何分块进行
  • 我决定在 python 中进行一些排序,然后使用它。我认为这将有助于解决文件大小问题。谢谢!

标签: javascript file


【解决方案1】:

您似乎正在尝试分块读取一个非常大的文件,以免因内存过多而导致浏览器崩溃,对吗?如果没有,请告诉我。

虽然一般来说,要“逐行”阅读,人们 (How to use Javascript to read local text file and read line by line?) 通常只是加载整个文件,然后将其拆分为 "\n",但这无法解决浏览器崩溃的问题过大的文件。

您要查找的是用于 FileReaderXMLHttpRequest 类的 progress event,具体取决于您是从服务器获取本地、用户选择的文件还是文件。

它应该允许您以块的形式读取较大文件的一部分。随着块的进入,您可以跟踪换行符 (\n),并相应地将每组文本保存在一个新数组中。

为了跟踪块,XMLHttpRequest chunked response, only read last response in progress,如果您可以在内存中保存累积的响应数据量,如果不是,您可以尝试How to write javascript in client side to receive and parse `chunked` response in time? 中提到的数组缓冲区方法,甚至更好,使用答案中提到的 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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-06
    • 2022-11-05
    • 2014-04-02
    • 2021-08-20
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多