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

NodeJS处理1.5GB大文本文件末尾:修复JSON格式问题

Node.js处理大文件生成合法JSON的方案

针对1.5GB的大文件,绝对不能一次性加载到内存处理,否则会直接导致内存溢出。下面提供两种高效的Node.js实现方案:

方案一:直接定位修改文件末尾(最优)

利用文件系统的随机读写能力,只操作文件末尾的少量内容,性能最高:

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

async function fixLargeJsonFile(filePath) {
  // 打开文件,获取文件描述符
  const fd = await fs.open(filePath, 'r+');
  try {
    // 获取文件总大小
    const { size } = await fd.stat();
    if (size === 0) {
      await fd.write('[]');
      return;
    }

    // 从文件末尾往前逐字节读取,寻找最后一个逗号的位置
    let pos = size - 1;
    let foundComma = false;
    // 最多往前检查100字节(足够覆盖末尾的换行、空格等)
    while (pos > 0 && pos >= size - 100) {
      const buffer = Buffer.alloc(1);
      await fd.read(buffer, 0, 1, pos);
      const char = buffer.toString();
      
      // 跳过换行、空格等空白字符
      if (char === '\n' || char === '\r' || char === ' ') {
        pos--;
        continue;
      }
      
      if (char === ',') {
        // 找到最后一个逗号,覆盖为']'
        await fd.write(Buffer.from(']'), 0, 1, pos);
        foundComma = true;
        break;
      } else {
        // 如果末尾没有逗号,直接追加']'(防止异常情况)
        await fd.write(Buffer.from(']'), 0, 1, size);
        break;
      }
    }

    // 如果没找到逗号(比如文件只有开头的'['),补全为'[]'
    if (!foundComma && pos === 0) {
      await fd.write(Buffer.from(']'), 0, 1, 1);
    }
  } finally {
    await fd.close();
  }
}

// 使用示例
fixLargeJsonFile('./your-large-file.txt')
  .then(() => console.log('文件修复完成'))
  .catch(err => console.error('修复失败:', err));

方案说明:

  • 仅操作文件末尾最多100字节,完全避免加载大文件到内存
  • 自动跳过末尾的换行、空格等空白字符,适配不同的文件结尾格式
  • 包含异常情况处理(空文件、无逗号的情况)

方案二:流式反向读取(兼容复杂场景)

如果文件末尾的空白字符较多,或者需要更灵活的匹配,可以用流式反向读取:

const fs = require('fs');
const { createReadStream } = require('fs');
const { promisify } = require('util');
const truncate = promisify(fs.truncate);
const appendFile = promisify(fs.appendFile);

function fixLargeJsonFileStream(filePath) {
  return new Promise((resolve, reject) => {
    const stats = fs.statSync(filePath);
    let currentPos = stats.size;
    let foundComma = false;

    // 创建从末尾反向读取的流
    const stream = createReadStream(filePath, {
      start: Math.max(0, currentPos - 1024),
      end: currentPos - 1,
      highWaterMark: 1
    });

    stream.on('data', (chunk) => {
      stream.pause();
      currentPos--;
      const char = chunk.toString();

      if (char === '\n' || char === '\r' || char === ' ') {
        stream.resume();
        return;
      }

      if (char === ',') {
        // 截断到逗号位置,然后追加']'
        truncate(filePath, currentPos)
          .then(() => appendFile(filePath, ']'))
          .then(resolve)
          .catch(reject);
        foundComma = true;
        stream.destroy();
      } else {
        // 无逗号,直接追加']'
        appendFile(filePath, ']')
          .then(resolve)
          .catch(reject);
        stream.destroy();
      }
    });

    stream.on('end', () => {
      if (!foundComma) {
        // 整个文件读完没找到逗号,说明只有'[',补全为'[]'
        appendFile(filePath, ']').then(resolve).catch(reject);
      }
    });

    stream.on('error', reject);
  });
}

// 使用示例
fixLargeJsonFileStream('./your-large-file.txt')
  .then(() => console.log('文件修复完成'))
  .catch(err => console.error('修复失败:', err));

方案说明:

  • 以1字节为单位反向读取,确保精准定位最后一个逗号
  • 同样避免加载整个文件,仅读取末尾的1KB内容(可调整)
  • 适合末尾有大量空白字符的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:43:37