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

Node.js 18.12中ReadableStream pipeTo写入本地文件失败求助

解决Node.js 18.12中GraphQL Yoga 3返回的ReadableStream写入本地文件的问题

错误原因

GraphQL Yoga 3返回的是Web标准的ReadableStream(遵循WHATWG规范),而fs.createWriteStream生成的是Node.js原生可写流,两者API体系不兼容。Web流的pipeTo方法仅接受Web标准的WritableStream,直接传入Node.js写流就会触发你遇到的类型错误。

可行解决方案

方案1:将Node.js写流转为Web标准WritableStream

Node.js 18+的原生流自带toWeb()方法,能把Node.js写流转换成Web标准的WritableStream,完美适配Web ReadableStream的pipeTo:

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

const outputPath = path.join(__dirname, 'test.png');
const nodeWriteStream = fs.createWriteStream(outputPath);
// 转换为Web标准可写流
const webWriteStream = nodeWriteStream.toWeb();

// stream 是GraphQL Yoga返回的Web ReadableStream
await stream.pipeTo(webWriteStream);
console.log('DONE');

方案2:将Web ReadableStream转为Node.js可读流

如果方案1遇到实例兼容性问题(比如第三方库实现的Web流不被Node.js识别),可以把Web流转成Node.js原生可读流,再用Node.js的pipe方法:

const fs = require('fs');
const path = require('path');
const { Readable } = require('stream');

const outputPath = path.join(__dirname, 'test.png');
const writeStream = fs.createWriteStream(outputPath);

// 转换Web流为Node.js可读流
const nodeReadable = Readable.fromWeb(stream);
// 使用Node.js原生pipe写入
nodeReadable.pipe(writeStream).on('finish', () => {
  console.log('DONE');
});

方案3:手动读取Web流内容写入文件

如果前两种方案都失效,直接手动读取Web流的所有数据块,再一次性写入文件:

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

const outputPath = path.join(__dirname, 'test.png');
const reader = stream.getReader();
const chunks = [];
let readResult;

// 逐块读取Web流内容
while (!(readResult = await reader.read()).done) {
  chunks.push(readResult.value);
}

// 合并数据块并写入文件
await fs.writeFile(outputPath, Buffer.concat(chunks));
console.log('DONE');

你尝试过的方法为什么失败

  1. new Readable().wrap(stream):这个方法是专门用来兼容Node.js v0.10之前的旧式流,完全不支持Web标准的ReadableStream,自然会报stream.on is not a function(Web流没有Node.js流的on事件方法)。
  2. Readable.fromWeb(stream):大概率是因为GraphQL Yoga返回的Web流由第三方库(如undici、@whatwg-node/fetch)实现,虽然符合Web标准,但Node.js的Readable.fromWeb对实例构造函数的检查过于严格,导致识别失败。这种情况下优先用方案1或方案3。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:20:14