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

NodeJS中如何在for循环内将对象写入数组格式的JSON文件?

解决JSON数组文件的追加写入问题

场景与问题

在for循环中执行axios POST请求,需将请求相关对象存入数组格式的JSON文件,且后续运行时要追加新对象、不覆盖原有内容。当前代码生成的JSON格式不符合标准,缺少数组方括号和对象间的分隔逗号。

当前代码

var arrayFile = fs.createWriteStream("arrayFile.json", {
    flags: "a"
})

for (var x = 0; x < 2; x++) {

    await axios
        .post(destinationURL, config)
        .then(res => {

            const obj = {
                id: x,
                user: config.user,
                password: config.password,
            }

            arrayFile.write(JSON.stringify(obj, null, 2), "utf-8")

        })
}

当前错误输出格式

{
  "id": 0,
  "user": "testUser1",
  "password": "ThisIsPassword"
}{
  "id": 1,
  "user": "testUser2",
  "password": "ThisIsPassword"
}

期望输出格式

[
    {
    "id": 0,
    "user": "testUser1",
    "password": "ThisIsPassword"
  },
  {
    "id": 1,
    "user": "testUser2",
    "password": "ThisIsPassword"
  }
]

解决方案

方案1:先收集数据再统一写入(小数据场景)

逻辑简单,先将所有请求结果存入内存数组,再合并到现有文件的数组中,适合数据量不大的情况。

const fs = require('fs').promises;
const axios = require('axios');

async function saveData() {
    const newData = [];

    // 批量执行请求,收集数据
    for (let x = 0; x < 2; x++) {
        await axios.post(destinationURL, config);
        newData.push({
            id: x,
            user: config.user,
            password: config.password
        });
    }

    let existingArray = [];
    try {
        // 读取现有文件内容
        const fileContent = await fs.readFile('arrayFile.json', 'utf-8');
        existingArray = JSON.parse(fileContent);
    } catch (err) {
        // 文件不存在时初始化空数组
        if (err.code !== 'ENOENT') throw err;
    }

    // 合并新旧数据并写入
    const finalData = [...existingArray, ...newData];
    await fs.writeFile('arrayFile.json', JSON.stringify(finalData, null, 2), 'utf-8');
}

saveData();

方案2:流式追加写入(大数据场景)

避免一次性加载大量数据到内存,通过操作文件指针实现流式追加,适合数据量较大的场景。

const fs = require('fs');
const fsPromises = require('fs').promises;
const axios = require('axios');

async function appendToJsonArray() {
    const filePath = 'arrayFile.json';
    let isFirstWrite = false;

    // 检查文件状态,判断是否为首次写入
    try {
        await fsPromises.access(filePath);
        const stats = await fsPromises.stat(filePath);
        
        if (stats.size === 0) {
            isFirstWrite = true;
        } else {
            // 定位到文件末尾,移除闭合的]
            const fd = await fsPromises.open(filePath, 'r+');
            await fd.seek(stats.size - 1);
            const buf = Buffer.alloc(1);
            await fd.read(buf, 0, 1, stats.size - 1);
            await fd.close();

            if (buf.toString() !== ']') {
                throw new Error('JSON文件格式异常,不是有效的数组');
            }
            await fsPromises.truncate(filePath, stats.size - 1);
        }
    } catch (err) {
        if (err.code === 'ENOENT') isFirstWrite = true;
        else throw err;
    }

    const stream = fs.createWriteStream(filePath, { flags: 'a' });
    // 写入数组开头或分隔符
    isFirstWrite ? stream.write('[', 'utf-8') : stream.write(',', 'utf-8');

    // 循环执行请求并写入对象
    for (let x = 0; x < 2; x++) {
        await axios.post(destinationURL, config);
        const objStr = JSON.stringify({
            id: x,
            user: config.user,
            password: config.password
        }, null, 2);

        // 保持格式美观,添加换行和缩进
        if ((isFirstWrite && x > 0) || (!isFirstWrite && x === 0)) {
            stream.write('\n    ', 'utf-8');
        } else if (x > 0) {
            stream.write(',\n    ', 'utf-8');
        }
        stream.write(objStr, 'utf-8');
    }

    // 写入数组闭合符
    stream.write('\n]', 'utf-8');
    stream.end();
}

appendToJsonArray();

注意事项

  • 方案1实现简单,易维护,但数据量过大时会占用较多内存。
  • 方案2内存占用低,但需处理文件格式异常等边界情况,建议添加完善的错误捕获逻辑。
  • 若请求可能失败,需添加回滚机制,避免破坏JSON文件格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:20:32