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

使用NodeJs从URL批量下载文件时生成空文件及报错如何解决?

问题根因

  • 同步循环瞬间发起大量并发请求、同时创建数百个文件写入流,超出系统允许的同时打开文件数上限,触发EMFILE报错
  • 你用var声明的file变量是函数作用域,不是块级作用域,所有请求的回调触发时,file已经被循环覆盖为最后一次创建的写入流,导致前面的请求数据都写到了最后一个文件里,其余文件都是空的
  • 写的setTimeout(sleep, 3000)完全不生效:首先你没定义sleep函数,其次定时器是异步的,不会阻塞同步for循环的执行,等于循环还是一瞬间跑完
  • 大量并发请求注册的事件监听器超过Node.js默认的事件监听器上限,触发MaxListenersExceededWarning

解决方法

通过并发控制限制同时运行的下载任务数即可解决所有问题,调整后的可运行代码如下:

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

// 配置项,可根据自身网络和系统情况调整
const MAX_CONCURRENT = 5; // 最大同时下载任务数
const TOTAL_DOWNLOAD = 500; // 总下载数量
const SAVE_DIR = "D:/SavePath/";

// 自动创建保存目录,无需手动提前新建
if (!fs.existsSync(SAVE_DIR)) {
  fs.mkdirSync(SAVE_DIR, { recursive: true });
}

let currentTaskIndex = 1;

// 单张图片下载逻辑
async function downloadSingle() {
  if (currentTaskIndex > TOTAL_DOWNLOAD) return;
  const taskId = currentTaskIndex++;
  const random = Math.floor(Math.random() * 1497791);
  const requestUrl = `https://cdnpath.com${random}.png`;
  const savePath = path.join(SAVE_DIR, `#${taskId}.png`);

  return new Promise((resolve, reject) => {
    const writeStream = fs.createWriteStream(savePath);
    http.get(requestUrl, (response) => {
      if (response.statusCode !== 200) {
        fs.unlink(savePath, () => {}); // 下载失败自动清理空文件
        return reject(new Error(`请求失败,状态码:${response.statusCode}`));
      }
      response.pipe(writeStream);
      writeStream.on('finish', () => {
        writeStream.close();
        console.log(`下载完成:${savePath}`);
        resolve();
      });
    }).on('error', (err) => {
      fs.unlink(savePath, () => {}); // 请求失败自动清理空文件
      reject(err);
    });
  }).finally(() => {
    // 单个任务完成后自动启动下一个任务
    return downloadSingle();
  });
}

// 启动下载
async function run() {
  // 初始化指定数量的并发任务
  const initialTasks = [];
  for (let i = 0; i < MAX_CONCURRENT; i++) {
    initialTasks.push(downloadSingle());
  }
  await Promise.all(initialTasks);
  console.log('全部图片下载完成');
}

run().catch(err => console.error('运行异常:', err));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:45:03