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

Node.js下载Census.gov 6GB大文件频繁中断的解决方法咨询

解决Node.js大文件下载中途中断问题

问题根源

你的代码缺少错误处理逻辑、未处理流的背压问题,且默认HTTP超时设置不足以支撑6GB大文件的长时间下载,这些都是导致下载中途中断的核心原因。

具体修复方案

1. 监听所有错误事件

HTTP请求流、文件写入流都可能因网络波动、磁盘异常等抛出错误,必须监听这些错误才能避免静默失败,并快速定位问题。

2. 处理流的背压

当file.write(chunk)返回false时,说明文件流暂时无法处理更多数据,此时需暂停HTTP响应流,等待文件流的drain事件触发后再恢复传输,否则会导致数据丢失或下载中断。

3. 调整HTTP请求超时

默认HTTP请求超时(通常2分钟)远不足以支撑大文件下载,需手动设置更长的超时时间,或直接禁用超时。

4. 实现断点续传(推荐)

若服务器支持Range请求,可记录已下载的文件大小,下次启动时从断点处继续下载,避免因网络中断重新下载整个文件。

修复后的完整代码

const fs = require('fs');
const http = require('http'); // 若目标地址是HTTPS,替换为https模块

const fileName = 'target-large-file.zip';
const url = 'http://census.gov/path/to/your/6gb-file.zip';

// 检查已下载文件大小,用于断点续传
let downloadedSize = 0;
if (fs.existsSync(fileName)) {
  const stats = fs.statSync(fileName);
  downloadedSize = stats.size;
}

const requestOptions = {
  headers: {
    // 支持断点续传时,添加Range请求头
    ...(downloadedSize > 0 ? { Range: `bytes=${downloadedSize}-` } : {})
  },
  timeout: 0 // 禁用超时,或设置足够大的值,比如3600000(1小时)
};

// 写入文件:续传用追加模式,全新下载用覆盖模式
const fileStream = fs.createWriteStream(fileName, { flags: downloadedSize > 0 ? 'a' : 'w' });

const httpRequest = http.get(url, requestOptions, (res) => {
  let totalFileSize = downloadedSize;
  // 处理续传响应(206 Partial Content)
  if (res.statusCode === 206) {
    const contentRange = res.headers['content-range'];
    totalFileSize = parseInt(contentRange.split('/')[1], 10);
  } else if (res.statusCode === 200) {
    totalFileSize = parseInt(res.headers['content-length'], 10);
  }

  let currentDownloaded = downloadedSize;
  res
    .on('data', (chunk) => {
      // 处理流背压
      const canWrite = fileStream.write(chunk);
      if (!canWrite) {
        res.pause();
      }
      currentDownloaded += chunk.length;
      process.stdout.write(`已下载 ${(currentDownloaded / 1000000).toFixed(2)} MB / 总计 ${(totalFileSize / 1000000).toFixed(2)} MB\r`);
    })
    .on('end', async () => {
      fileStream.end();
      console.log(`${fileName} 下载完成。`);
      // 下载完成后执行你的zip处理逻辑
      // await processZipFile(fileName);
    })
    .on('error', (err) => {
      console.error('HTTP响应流错误:', err);
      fileStream.close();
    });

  // 文件流可继续写入时,恢复HTTP流传输
  fileStream.on('drain', () => {
    res.resume();
  });

  // 文件写入错误处理
  fileStream.on('error', (err) => {
    console.error('文件写入错误:', err);
    httpRequest.abort();
  });
});

// 请求超时处理
httpRequest.on('timeout', () => {
  console.error('请求超时');
  httpRequest.abort();
});

// 请求发起阶段错误处理
httpRequest.on('error', (err) => {
  console.error('HTTP请求错误:', err);
  fileStream.close();
});

额外注意事项

  • 确保磁盘有足够空间存储6GB文件。
  • 若目标地址是HTTPS,需将代码中的http模块替换为https模块。
  • 可添加重试逻辑,当下载失败时自动触发断点续传重试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 10:18:18