You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js实现大JSON文件内容追加及正确格式化方案咨询

大JSON数组文件追加合并方案

核心思路

因为文件体积大(超50K行),不能一次性加载到内存,必须用流式处理:

  • 截断原JSON数组文件的结尾]
  • 写入逗号作为元素分隔符
  • 读取待追加的JSON数组文件,跳过开头的[,将所有元素内容追加到原文件
  • 最后写入],恢复合法的JSON数组结构

具体实现(Node.js)

1. 依赖模块

仅需Node.js内置的fs和stream模块,无需额外安装第三方包。

2. 代码示例

const fs = require('fs');
const { Transform } = require('stream');

async function mergeJsonArrays(sourcePath, appendPath) {
  // 第一步:处理源文件,截断末尾的]
  const sourceStats = await fs.promises.stat(sourcePath);
  let endPosition = sourceStats.size;
  
  // 从文件末尾反向读取,找到真正的]位置(处理可能的换行/空格)
  const buffer = Buffer.alloc(1024);
  const fd = await fs.promises.open(sourcePath, 'r+');
  let found = false;
  
  while (endPosition > 0 && !found) {
    const readSize = Math.min(1024, endPosition);
    await fd.read(buffer, 0, readSize, endPosition - readSize);
    for (let i = readSize - 1; i >= 0; i--) {
      if (buffer[i] === 93) { // ASCII码对应]
        endPosition = endPosition - readSize + i;
        found = true;
        break;
      }
    }
    if (!found) endPosition -= readSize;
  }
  
  if (!found) {
    await fd.close();
    throw new Error('源文件不是合法的JSON数组');
  }
  
  // 截断到]之前的位置
  await fd.truncate(endPosition);
  // 写入逗号分隔符
  await fd.write(',', endPosition);
  await fd.close();

  // 第二步:追加待合并的JSON数组内容(跳过开头的[)
  const skipPrefix = new Transform({
    transform(chunk, encoding, callback) {
      if (!this.prefixSkipped) {
        // 找到第一个[的位置,截取之后的内容
        const str = chunk.toString();
        const bracketIndex = str.indexOf('[');
        if (bracketIndex !== -1) {
          this.push(str.slice(bracketIndex + 1));
          this.prefixSkipped = true;
        } else {
          // 整个chunk里没有[,直接丢弃
          this.push('');
        }
      } else {
        this.push(chunk);
      }
      callback();
    }
  });

  await new Promise((resolve, reject) => {
    const readStream = fs.createReadStream(appendPath);
    const writeStream = fs.createWriteStream(sourcePath, { flags: 'a' });

    readStream
      .pipe(skipPrefix)
      .pipe(writeStream)
      .on('finish', resolve)
      .on('error', reject);
  });

  // 第三步:写入结尾的],恢复合法JSON结构
  await fs.promises.appendFile(sourcePath, ']');
}

// 使用示例
mergeJsonArrays('./source.json', './to-append.json')
  .then(() => console.log('合并完成'))
  .catch(err => console.error('合并失败:', err));

关键注意事项

  • 格式校验:确保两个输入文件都是合法的JSON数组,否则合并后会生成无效JSON。可以先用JSON.parse验证小片段,或在流处理中增加格式检查逻辑。
  • 内存优化:所有操作都是流式处理,不会一次性加载整个文件,避免内存溢出。
  • 备份原文件:合并前务必备份源文件,防止操作失误导致数据丢失。
  • 异常处理:代码中加入了基础的错误捕获,实际使用时可扩展处理文件权限、磁盘空间不足等场景。

常见问题修正

如果之前用fs.readFile直接读取整个文件导致内存问题,替换成上述流式处理即可解决;如果合并后JSON格式错误,大概率是没有正确处理数组的[和],或是源文件末尾有多余空格/换行,代码中反向查找]的逻辑已处理这类情况。

内容的提问来源于stack exchange,提问作者Harihara Ganesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:50:18