Nodejs 文件(或目录)复制操作完成后 回调

本文探讨了三种方法实现将目录a中的文件和子目录复制到目录b,并在复制完成后调用回调。方法包括计数器跟踪、同步复制与Promise.all,以及优化耗时和准确性。适合处理远程下载与清理任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

现在需要实现这样一个功能,将目录a中所有文件及文件夹复制到目录b,并在整个操作完成后,执行一次某个方法,或者一个回调。

有几种方法可以尝试实现上述功能

  1. 遍历目录及文件前,给个计数器,初始值设置在null,文件/目录每读取一个文件,计数器数量增加1(若初始值为null,则直接赋值1),复制完成后数量减少1,每隔某个时间后读取计数器,若计数器不是null并且是0,则表示已经复制完成,调用回调方法。

    这种方法 计数可能会不准

  2. 遍历目录中都使用同步的方法,nodejs中fs库大部分方法都有同步的实现,比如说fs.stat有fs.statSync。在复制完成后执行回调。

    这种方法可能会耗时过长,代码阻塞

另一种方法是使用fs的同步方法+promise.all,同步读取目录,异步处理文件复制,promise.all回调来执行复制文件完成的回调

// copyfile.js
const path = require('path')
const fs = require('fs')

module.exports = function (fromDir, toDir) {
    if (!fromDir || !toDir || fromDir == toDir) {
        return Promise.reject(new Error(`参数无效:${fromDir} - ${toDir}`))
    }
    return new Promise((resolve, reject) => {
        !fs.existsSync(toDir) && fs.mkdirSync(toDir, {recursive: true})
        const task = []
        readFileSync(fromDir, toDir, (fromFullPath, toFullPath, stat) => {
            task.push({
                fromFullPath, toFullPath, stat
            })
        })
        Promise.all(task.map(k => loopCopyFilePromise(k))).then(resolve).catch(e => reject(e))
    })
}


function readFileSync(fromDir, toDir, cb) {
    const method = arguments.callee;
    const fileList = fs.readdirSync(fromDir)
    fileList.forEach((name) => {
        const fromFullPath = path.join(fromDir, name)
        const toFullPath = path.join(toDir, name)
        const stat = fs.statSync(fromFullPath)
        if (stat.isDirectory()) {
            !fs.existsSync(toFullPath) && fs.mkdirSync(toFullPath, {recursive: true})
            method(fromFullPath, toFullPath, cb)
        }
        if (stat.isFile()) {
            cb(fromFullPath, toFullPath, stat)
        }
    })
}

function loopCopyFilePromise(args) {
    const {fromFullPath, toFullPath, stat} = args
    if (stat.size > 10000) {
        return new Promise((resolve, reject) => {
            const readStream = fs.createReadStream(fromFullPath),
                writeStream = fs.createWriteStream(toFullPath)
            readStream.pipe(writeStream)
            writeStream.on('finish', resolve)
            writeStream.on('error', reject)
        })
    } else {
        return new Promise((resolve, reject) => {
            fs.copyFile(fromFullPath, toFullPath, (err) => {
                err ? reject() : resolve();
            });
        })
    }
}

模块返回一个promise,可以直接在then方法加回调

const copyfile = require("。/filecopy")

console.log('start...')
copyfile("./dirA",'./dirB').then(()=>{
	console.log("这里执行回调")
    console.log("end...")
})

有时候会有这样的使用场景,从远程上下载文件到某个临时目录,然后复制到某个指定的目录,最后删除临时目录,此时就需要在文件复制完成后,执行清理工作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值