javascript - 如何在 Node.js 中为超大(> 1GB)文件的每一行运行异步函数

标签 javascript node.js asynchronous stream filestream

假设您有一个巨大的 (> 1GB) CSV 记录 ID:

655453
4930285
493029
4930301
493031
...

对于每个 id您想调用 REST API 来获取记录数据,在本地转换它,然后将其插入本地数据库。

如何使用 Node.js 的 Readable Stream 做到这一点?

我的问题基本上是这样的:如何逐行读取一个非常大的文件,为每一行运行一个异步函数,并且[可选]能够从特定行开始读取文件?

从下面的 Quora 问题我开始学习使用 fs.createReadStream :

http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js

var fs = require('fs');
var lazy = require('lazy');

var stream = fs.createReadStream(path, {
  flags: 'r',
  encoding: 'utf-8'
});

new lazy(stream).lines.forEach(function(line) {
  var id = line.toString();
  // pause stream
  stream.pause();
  // make async API call...
  makeAPICall(id, function() {
    // then resume to process next id
    stream.resume();
  });
});

但是,该伪代码不起作用,因为 lazy module强制您读取整个文件(作为流,但没有暂停)。所以这种方法似乎行不通。

另一件事是,我希望能够从特定行开始处理该文件。这样做的原因是,处理每个 id (进行 api 调用、清理数据等)每条记录最多可能需要半秒,所以我不想每次都从文件的开头开始。我正在考虑使用的天真的方法是只捕获最后处理的 id 的行号,并保存它。然后,当您再次解析文件时,逐行流式处理所有 ID,直到找到您离开的行号,然后执行 makeAPICall。商业。另一种天真的方法是编写小文件(比如 100 个 ID)并一次处理每个文件(足够小的数据集可以在没有 IO 流的情况下在内存中执行所有操作)。有更好的方法吗?

我可以看出这是多么棘手(以及 node-lazy 的来源),因为 chunkstream.on('data', function(chunk) {});可能只包含一行的部分(如果 bufferSize 很小,每个 block 可能是 10 行,但因为 id 是可变长度,它可能只有 9.5 行或其他)。这就是为什么我想知道解决上述问题的最佳方法是什么。

最佳答案

与Andrew Андрей Листочкин的回答相关:

您可以使用类似 byline 的模块为每一行获取一个单独的 data 事件。它是围绕原始文件流的转换流,它为每个 block 生成一个 data 事件。这让您可以在每行之后暂停。

byline 不会像 lazy 那样将整个文件读入内存。

var fs = require('fs');
var byline = require('byline');

var stream = fs.createReadStream('bigFile.txt');
stream.setEncoding('utf8');

// Comment out this line to see what the transform stream changes.
stream = byline.createStream(stream); 

// Write each line to the console with a delay.
stream.on('data', function(line) {
  // Pause until we're done processing this line.
  stream.pause();

  setTimeout(() => {
      console.log(line);

      // Resume processing.
      stream.resume();
  }, 200);
});

关于javascript - 如何在 Node.js 中为超大(> 1GB)文件的每一行运行异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11078141/

相关文章:

node.js - 生产/构建中的 Material-UI 渲染错误

javascript - TypeError : Cannot read property 'then' of undefined. 当我尝试运行 updatefirst 函数时出现此错误

javascript - 使用 jQuery 文本对齐子元素

MySql After Update 触发器执行顺序

javascript - 如何在菜单外部添加单击按钮以打开新的文本字段,而不是单击 "other"?

node.js - 如何在 Windows 中使用 yarn 运行简单的文件脚本

node.js - 如何将不同请求的响应与nodejs和请求放在同一个文档中?

c# - 从属性 setter 调用异步方法

javascript - 如何更改 jquery mobile 中面板的高度?

javascript - PHP 与 onclick 函数