【问题标题】:How do I use the pipeline from stream-json to write to file, in nodeJs?如何在 nodeJs 中使用 stream-json 中的管道写入文件?
【发布时间】:2021-11-07 14:27:54
【问题描述】:

我正在尝试使用stream-json 读取压缩文件,将其解压缩,然后将其写入文件。我不认为我了解如何使用该库。

根据上面的链接,他们有这个例子:

const {chain}  = require('stream-chain');

const {parser} = require('stream-json');
const {pick}   = require('stream-json/filters/Pick');
const {ignore} = require('stream-json/filters/Ignore');
const {streamValues} = require('stream-json/streamers/StreamValues');

const fs   = require('fs');
const zlib = require('zlib');

const pipeline = chain([
  fs.createReadStream('sample.json.gz'),
  zlib.createGunzip(),
  parser(),
  pick({filter: 'data'}),
  ignore({filter: /\b_meta\b/i}),
  streamValues(),
  data => {
    const value = data.value;
    // keep data only for the accounting department
    return value && value.department === 'accounting' ? data : null;
  }
]);

let counter = 0;
pipeline.on('data', () => ++counter);
pipeline.on('end', () =>
  console.log(`The accounting department has ${counter} employees.`));

但是我不想计算任何东西,我只想写入文件。这是我的工作:

function unzipJson() {
  const zipPath = Path.resolve(__dirname, 'resources', 'AllPrintings.json.zip');
  const jsonPath = Path.resolve(__dirname, 'resources', 'AllPrintings.json');
  console.info('Attempting to read zip');
  return new Promise((resolve, reject) => {
    let error = null;
    Fs.readFile(zipPath, (err, data) => {
      error = err;
      if (!err) {
        const zip = new JSZip();
        zip.loadAsync(data).then((contents) => {
          Object.keys(contents.files).forEach((filename) => {
            console.info(`Writing ${filename} to disk...`);
            zip.file(filename).async('nodebuffer').then((content) => {
              Fs.writeFileSync(jsonPath, content);
            }).catch((writeErr) => { error = writeErr; });
          });
        }).catch((zipErr) => { error = zipErr; });
        resolve();
      } else if (error) {
        console.log(error);
        reject(error);
      }
    });
  });
}

但是我不能轻易地为此添加任何处理,所以我想用stream-json 替换它。这是我的部分尝试,因为我不知道如何完成:

function unzipJson() {
  const zipPath = Path.resolve(__dirname, 'resources', 'myfile.json.zip');
  const jsonPath = Path.resolve(__dirname, 'resources', 'myfile.json');
  console.info('Attempting to read zip');
  const pipeline = chain([
    Fs.createReadStream(zipPath),
    zlib.createGunzip(),
    parser(),
    Fs.createWriteStream(jsonPath),
  ]);
  // use the chain, and save the result to a file
  pipeline.on(/*what goes here?*/)

稍后我打算添加对 json 文件的额外处理,但我想在开始投入额外功能之前学习基础知识。

不幸的是,我无法提供一个最小的示例,因为我不知道 pipeline.on 函数中的内容。我试图了解我应该做什么,而不是我做错了什么。

我还查看了相关的stream-chain,其中有一个这样结束的示例:

// use the chain, and save the result to a file
dataSource.pipe(chain).pipe(fs.createWriteStream('output.txt.gz'));`

但是文档根本没有解释dataSource 的来源,我认为我的链是通过从文件中读取 zip 来创建它自己的?

我应该如何使用这些流媒体库来写入文件?

【问题讨论】:

  • 如果你想写一个 json 文件而不改变其中的任何东西,你根本不需要解析它。像对待任何其他文本文件一样对待它。 json-parser不需要参与解压。
  • chain([fs.createReadStream(zipPath), zlib.createGunzip(), fs.createWriteStream(jsonPath)]);fs.createReadStream(zipPath).pipe(zlib.createGunzip()).pipe(fs.createWriteStream(jsonPath)); 应该这样做。
  • "pipeline.on(/*what goes here?*/)" - 错误处理和等待管道完成。
  • @bergi 创建链会执行吗?我虽然它只是定义了当它被调用/执行/激活等时要做什么?
  • 我不知道 stream-chain 库,但一般调用 pipe 确实会启动流

标签: javascript node.js json node-streams


【解决方案1】:

我不想计算任何东西,我只想写入文件

在这种情况下,您需要将令牌/JSON 数据流转换回可以写入文件的文本流。您可以为此使用图书馆的Stringer。它的文档还包含一个似乎更符合您想要做的示例:

chain([
  fs.createReadStream('data.json.gz'),
  zlib.createGunzip(),
  parser(),
  pick({filter: 'data'}), // omit this if you don't want to do any processing
  stringer(),
  zlib.Gzip(),            // omit this if you want to write an unzipped result
  fs.createWriteStream('edited.json.gz')
]);

【讨论】:

  • 你说:“我不知道流链库,但一般调用管道确实启动流”,你能举个调用管道的例子吗?
  • @Pureferret 查看stream-chain packagenode stream api 的文档
  • 我已经阅读了那些,这就是我在这里问的原因。如果你不知道没关系,我可以等待另一个答案。如果有帮助,我已经更新了我的问题。
  • @Pureferret 不确定问题出在哪里。代码不起作用吗?我认为stream-chain 如果将可读流作为第一个值,将可写流作为最后一个值使用,则管道本身会进行。
  • 最初我认为由于错误而无法正常工作,但我认为我的错误与我的 zip 格式有关。感谢您澄清我最终造成的一些愚蠢的困惑!
猜你喜欢
  • 2013-04-12
  • 2020-11-02
  • 2022-11-03
  • 1970-01-01
  • 2018-02-07
  • 2017-10-05
  • 2019-02-22
  • 2012-11-13
  • 1970-01-01
相关资源
最近更新 更多