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

NodeJS中createWriteStream实例遮蔽另一实例的原因与解决方法

问题分析与解决

为什么第一个流会遮蔽第二个流?

核心有两个原因:

  1. 写流的异步特性:fs.createWriteStream的写入操作是异步的,w.write()只是把数据放到内存缓冲区,真正写入磁盘是后台异步完成的。你同步调用writer1和writer2,两个流会同时抢占同一个文件的写入权限,操作系统无法保证写入顺序,导致内容互相覆盖。
  2. 'w'标志的截断行为:使用flags:'w'打开文件时,只要成功打开就会立即清空文件内容,不管这个文件当前有没有其他流在操作。当writer2打开文件时,会先截断文件,但此时writer1的缓冲区数据还在陆续写入磁盘,最终writer1的内容会覆盖writer2的写入结果。

如何避免这种情况?

关键是串行化写操作,确保前一个写流的所有数据都完全写入磁盘(触发finish事件)后,再执行下一个写流。同时正确判断文件是否存在,只在需要时执行writer1。

修正后的代码示例

const fs = require('fs').promises;
const { createWriteStream } = require('fs');

// 将writer1改为返回Promise,等待写入完成
function writer1(data, file) {
  return new Promise((resolve, reject) => {
    const w = createWriteStream(file, { flags: 'w' });
    
    for (let i = 0; i < data.length; i++) {
      // 处理缓冲区满的情况,避免数据丢失
      if (!w.write(data[i])) {
        w.once('drain', () => {});
      }
    }
    
    w.end();
    w.on('finish', resolve); // 所有数据写入完成后触发
    w.on('error', reject);
  });
}

// 同样改造writer2
function writer2(data, file, excludeStr) {
  return new Promise((resolve, reject) => {
    const w = createWriteStream(file, { flags: 'w' });
    
    for (let i = 0; i < data.length; i++) {
      if (data[i] !== excludeStr) {
        if (!w.write(data[i])) {
          w.once('drain', () => {});
        }
      }
    }
    
    w.end();
    w.on('finish', resolve);
    w.on('error', reject);
  });
}

// 主逻辑:先判断文件是否存在,再串行执行操作
async function processData(data, file, excludeStr) {
  let fileExists = false;
  try {
    await fs.access(file); // 检查文件是否存在
    fileExists = true;
  } catch {
    fileExists = false;
  }

  // 仅文件不存在时执行writer1,等待完成后再执行writer2
  if (!fileExists) {
    await writer1(data, file);
  }
  await writer2(data, file, excludeStr);
}

// 调用示例
processData(data, "file.txt", "some string").catch(err => console.error('写入失败:', err));

补充说明

  • 改造后的函数通过Promise封装,利用async/await实现串行执行,彻底避免了并发写入的冲突。
  • 增加了drain事件的处理,防止因缓冲区满导致的数据丢失(原代码中如果数据量较大,可能会丢失部分数据)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:55:15