代码之家  ›  专栏  ›  技术社区  ›  1252748

使用节点流将json附加到文件

  •  0
  • 1252748  · 技术社区  · 6 年前

    根据我所读的 here 我在用 fs.createWriteStream 将一些json写入文件。我正在处理大约50块的数据。所以在脚本的开头,我打开了我的流,然后使用一个函数来传递它,以及一些json,这对编写非常有用。

    const myStream = fs.createWriteStream(
      path.join(RESULTS_DIR, `my-file.json`),
      {
        flags: 'a'
      }
    )
    
    
    function appendJsonToFile(stream, jsonToAppend) {
      return new Promise((resolve, reject) => {
        try {
          stream.write(JSON.stringify(jsonToAppend, null, 2)
          resolve('STREAM_WRITE_SUCCESS')
        } catch (streamError) {
          reject('STREAM_WRITE_FAILURE', streamError)
        }
      })
    }
    
    appendJsonToFile(myStream, someJson)
    

    但是,由于要写入的每一段数据都是一个对象数组,因此我最终在文件中获得的结构将如下所示:

    [
        {
            "data": "test data 1",
        },
            {
            "data": "test data 2",
        }
    ][
        {
            "data": "test data 3",
        },
            {
            "data": "test data 4",
        }
    ]
    

    如何附加这些数据片段,使结果的格式正确,而不仅仅是一系列数组json?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Michał Karpacki    6 年前

    如果文件的格式总是如您在上面所说,那么您需要做的三件事是:

    1. 找出文件的当前长度并减去2个字符( \n] ,因为结尾没有换行符,
    2. 删除要保存的json的第一个字符,
    3. 使用保存文件 r+ 模式和 start
    4. 每次保存后结束流。

    这是链接到 createWriteStream options .

    另一件事是,第4点让这变得相当低效,并质疑是否应该在这里使用流媒体。我认为这是有道理的,但这里的问题是,如果您需要文件在两次写入之间可读-如果不是,那么您应该使用 transform stream 在文件中间添加flush in( beforeExit )你只是结束了这条河。

    根据定义,您可以这样做,但我是名为 scramjet 这使得这些案件变得更加容易:

    const myStream = new scramjet.DataStream();
    
    const file = path.join(RESULTS_DIR, `my-file.json`)
    const start = fs.statSync(file).size - 2;
    
    myStream
        .flatten()
        .toJSONArray()
        .shift(1)
        .pipe(fs.createWriteStream(
            file,
            {flags: 'r+', start}
        ));
    
    function appendJsonToFile(stream, jsonToAppend) {
        return new Promise((resolve, reject) => {
            try {
                stream.write(jsonToAppend)
                resolve('STREAM_WRITE_SUCCESS')
            } catch (streamError) {
                reject('STREAM_WRITE_FAILURE', streamError)
            }
        })
    }
    
    appendJsonToFile(myStream, someJson)
    
    process.on('beforeExit', myStream.end());
    

    您可以如上所述使用它,但是如果您希望使用纯节点流来处理这个问题,那么应该将您推向正确的方向。