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

Node.js使用Transform流传输对象数组写入文件报错排查

错误原因

这个类型错误的核心是流传输的数据类型和下游要求不匹配:

  • Node.js的文件可写流(fs.createWriteStream创建的流)默认只接受字符串、Buffer、Uint8Array类型的数据,无法直接写入JS对象。
  • 你代码里的new Buffer(obj2)写法是无效的:Buffer构造函数不支持直接接收普通JS对象,传入后只会生成内容为[object Object]的无效Buffer,本质上你还是在尝试向下游传递对象类型数据。
  • 你提到的objectMode: true配置只是让流支持传递JS对象,不代表非对象模式的文件流可以接收对象,而且你大概率没有给所有处理对象的流节点正确配置该参数,也没有做对象到可写入文本/二进制的转换。
修复方法

你需要在管道中增加一步格式转换:所有处理对象的流节点开启对象模式,在写入文件前,把处理完成的JS对象转换成文件流支持的字符串/Buffer格式。
修正后的可运行代码如下:

const stream = require('stream');
const fs = require('fs');
const util = require('util');
const { pipeline } = require('stream/promises');

// 此处替换为你的实际数据源
const res = [
  { id: 1, name: 'demo', inner: [{ val: 'a' }, { val: 'b' }] }
];
// 从对象数组创建可读流,默认自动开启对象模式
const readStream = stream.Readable.from(res);

// 自定义展开转换流
function Flatten(options) {
  // 显式开启对象模式,支持接收、输出JS对象
  stream.Transform.call(this, { ...options, objectMode: true });
}
util.inherits(Flatten, stream.Transform);
Flatten.prototype._transform = function (chunk, enc, cb) {
  const sourceObj = chunk;
  // 增加边界判断,避免inner不存在时遍历报错
  if (!Array.isArray(sourceObj.inner)) {
    return cb();
  }
  for (let j = 0; j < sourceObj.inner.length; j++) {
    const merged = { ...sourceObj, ...sourceObj.inner[j] };
    delete merged.inner;
    // 直接推送处理完成的对象,不要用Buffer包裹对象
    this.push(merged);
  }
  cb();
};

// 新增格式转换流:将JS对象转为文件可写入的字符串
const objectToStringStream = new stream.Transform({
  objectMode: true, // 接收上游传递的对象
  transform(chunk, enc, cb) {
    // 此处可根据你的需求调整输出格式:
    // 存JSON行格式就用JSON.stringify加换行,存CSV就拼接CSV行字符串
    const outputLine = JSON.stringify(chunk) + '\n';
    cb(null, outputLine);
  }
});

const flattenTransform = new Flatten();
const writeStream = fs.createWriteStream('test1.txt');

// 按顺序串联管道:读流 -> 对象展开 -> 格式转字符串 -> 写文件
await pipeline(readStream, flattenTransform, objectToStringStream, writeStream);
注意事项
  • 废弃的new Buffer()写法不要再用,当前Node.js版本创建Buffer请使用Buffer.from(),且该方法同样不支持直接传入普通对象,必须传入字符串、字节数组、Buffer实例等合法参数。
  • 如果你需要输出CSV、自定义文本等其他格式,只需要修改objectToStringStream中的转换逻辑,将对象拼接为对应格式的字符串即可。
  • 对象模式仅在需要传递JS对象的流节点上开启即可,最后对接文件流的节点输出必须是字符串/Buffer类型,文件流本身不需要开启对象模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:27:17