Nodejs大文件的下载以及断点续传

Nodejs大文件的下载以及断点续传

good ,但最好不要用 nodejs 来做这种 吃力不讨好的工作

7 回复

Nodejs大文件的下载以及断点续传

在处理大文件的下载及断点续传时,Node.js 提供了强大的功能来实现这些需求。虽然有些人可能认为使用 Node.js 进行这类操作会比较吃力,但通过适当的工具和技术,可以有效地完成任务。

1. 基本概念

  • 断点续传:当下载中断后,可以从上次中断的位置继续下载,而不是从头开始。
  • HTTP Range 请求:客户端可以通过 HTTP Range 头来请求文件的一部分,服务器则响应这部分内容。

2. 实现步骤

步骤1: 发送初始请求获取文件大小
const http = require('http');

function getFileSize(url) {
    return new Promise((resolve, reject) => {
        const req = http.get(url, res => {
            const fileSize = res.headers['content-length'];
            resolve(Number(fileSize));
        });
        req.on('error', err => reject(err));
    });
}
步骤2: 检查已下载部分
const fs = require('fs');
const path = require('path');

function getDownloadedBytes(filePath) {
    if (fs.existsSync(filePath)) {
        return fs.statSync(filePath).size;
    }
    return 0;
}
步骤3: 发送带有 Range 头的请求
function downloadFile(url, filePath) {
    const downloadedBytes = getDownloadedBytes(filePath);
    const start = downloadedBytes;
    const end = '';

    const headers = {
        'Range': `bytes=${start}-${end}`
    };

    const fileStream = fs.createWriteStream(filePath);

    http.get({ url, headers }, res => {
        res.pipe(fileStream);
        res.on('end', () => console.log('Download complete'));
    }).on('error', err => {
        fileStream.close();
        console.error(`Error: ${err.message}`);
    });
}

3. 使用示例

const url = 'http://example.com/largefile.zip';
const filePath = './largefile.zip';

getFileSize(url)
    .then(totalSize => {
        console.log(`Total file size: ${totalSize} bytes`);
        downloadFile(url, filePath);
    })
    .catch(err => console.error(err));

总结

以上代码展示了如何使用 Node.js 实现大文件的下载以及断点续传。通过发送带有 Range 头的请求,可以从上次中断的地方继续下载,从而提高效率。当然,实际应用中还需要考虑错误处理、日志记录等其他方面。


谢谢,以后会用到。

请问你这个断点续传有完整代码吗?能开源不?

代码跑了以后,下载的文件没有名字、后缀名,怎么办?

在头文件中添加"Content-Diposition"就会出现文件名和后缀,如: var filename =‘test.rar’; res.setHeader(‘Content-Disposition’, ‘attachment; filename=’+encodeURIComponent(filename));

对于“Nodejs大文件的下载以及断点续传”的问题,虽然确实有一些技术挑战,但使用Node.js来处理这样的任务是可行的。断点续传功能可以让用户在下载过程中断后重新连接时从上次中断的地方继续下载,从而提高用户体验。

示例代码

以下是一个简单的示例,展示如何使用Node.js实现基本的大文件下载及断点续传:

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

const url = 'http://example.com/largefile.zip'; // 目标文件的URL
const savePath = path.join(__dirname, 'largefile.zip'); // 文件保存路径

function downloadFile(url, savePath, resumePoint) {
    const file = fs.createWriteStream(savePath);
    let headers = {};

    const req = http.get(url, (res) => {
        headers = res.headers;
        if (resumePoint) {
            res.resume(resumePoint); // 如果有断点,则从断点处继续下载
        }
        res.pipe(file);
    });

    req.on('response', (data) => {
        if (data.statusCode === 302 || data.statusCode === 301) { // 处理重定向
            const newUrl = data.headers.location;
            downloadFile(newUrl, savePath, resumePoint);
        }
    });

    file.on('finish', () => {
        console.log('Download Complete');
    });

    file.on('error', (err) => {
        console.error(err.message);
        fs.unlink(savePath, () => {}); // 删除临时文件
    });
}

downloadFile(url, savePath, 1024 * 1024); // 假设已经下载了1MB

解释

  • fs 模块用于读写文件。
  • http 模块用于发起HTTP请求。
  • path 模块用于处理文件路径。
  • downloadFile 函数 接收目标URL、保存路径和已下载的字节数作为参数。
  • resume 方法 可以用来从指定位置开始读取数据。
  • 处理重定向 通过监听 response 事件来处理可能的302或301重定向状态码。
  • 错误处理 包括文件写入错误,删除临时文件。

此代码提供了一个基本框架,你可以根据具体需求进行调整和优化。

回到顶部