Node.js将子目录的内容移动到当前目录

时间:2016-07-06 23:17:25

标签: node.js

我有一个Node脚本,可以将zip下载到tmp/archive.zip并将其提取到tmp/archive

我想将tmp/archive的内容移至.。我很难找到如何以相当于fs.rename的方式使用mv tmp/archive/* .

我尝试了fs.rename('tmp/archive/*', '.', function(err){,但这给了我以下错误:Error: ENOENT: no such file or directory, rename 'tmp/archive/*' -> '.'

我还尝试使用glob列出tmp/archive的内容,然后遍历它并使用fs-extra的移动移动文件,如下所示:

glob('tmp/archive/*', {}, function(err, files){
    for (var i = files.length - 1; i >= 0; i--) {
      fs.move(files[i], '.', function(err){});
    }
}.bind(this));

导致出现以下错误:Error: EEXIST: file already exists, link 'tmp/archive/subdirectory' -> '.'

我可以从脚本中调用mv tmp/archive/* .但我想尽可能避免这种情况。有什么明显的东西我不见了吗?我怎么能这样做呢?

1 个答案:

答案 0 :(得分:2)

这是将文件目录从一个位置移动到另一个位置的一种方法(假设它们位于同一卷上,因此可以重命名而不是复制):

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
var path = require('path');

function moveFiles(srcDir, destDir) {
    return fs.readdirAsync(srcDir).map(function(file) {
        var destFile = path.join(destDir, file);
        console.log(destFile);
        return fs.renameAsync(path.join(srcDir, file), destFile).then(function() {
            return destFile;
        });
    });
}

// sample usage:
moveFiles(path.join(".", "tempSource"), path.join(".", "tempDest")).then(function(files) {
    // all done here
}).catch(function(err) {
    // error here
});

这会将srcDir中的文件和子目录移动到destDir。由于fs.rename()将同时移动子目录,因此您不必递归遍历。

在设计这样的函数时,您可以选择错误行为。上述实现在第一次错误时中止。您可以更改实现以移动所有文件,然后只返回无法移动的文件列表。

这是一个重命名所有文件的版本,如果有任何错误,它会在最后拒绝失败的文件列表及其错误对象:

function moveFilesAll(srcDir, destDir) {
    return fs.readdirAsync(srcDir).map(function(file) {
        var destFile = path.join(destDir, file);
        var srcFile = path.join(srcDir, file);
        return fs.renameAsync(srcFile, destFile).then(function() {
            return {file: srcFile, err: 0};
        }).catch(function(err) {
            console.log("error on " + srcFile);
            return {file: srcFile, err: err}
        });
    }).then(function(files) {
        var errors = files.filter(function(item) {
            return item.err !== 0;
        });
        if (errors.length > 0) {
            // reject with a list of error files and their corresponding errors
            throw errors;
        }
        // for success, return list of all files moved
        return files.filter(function(item) {
            return item.file;
        });
    });
}

// sample usage:
moveFilesAll(path.join(".", "tempSource"), path.join(".", "tempDest")).then(function(files) {
    // all done here
}).catch(function(errors) {
    // list of errors here
});