将目录中的所有文件移至使用node.js的父项

有一个简单的方法来移动目录中的所有文件直到它的父目录,然后删除目录?

用例

我正在做一个zip解压缩,源zip文件包含一个名为archive的根文件夹,所以当我解压时,我得到了extract_path/archive/ ,但是我想直接将archive的内容提取到extract_path

我以为这将是简单的重命名,但下面是抛出一个“有一个文件的方式”错误消息。

 fs.renameSync(extractPath + "/archive", extractPath) 

使用mv npm模块。 mv首先尝试fs.rename,如果失败,则使用copy然后取消链接:

 mv('source/dir', 'dest/a/b/c/dir', {mkdirp: true}, function(err) { // done. it first created all the necessary directories, and then // tried fs.rename, then falls back to using ncp to copy the dir // to dest and then rimraf to remove the source dir }); 

或者产生一个subprocess:

 var spawn = require('child_process').spawn, mv = spawn('mv', ['/dir1/dir2/*','dir1/']); 

所选答案不起作用:

 var mv = require('mv'); var extractPath = 'E:\\tmp\\dir'; mv(extractPath + "\\sub", extractPath, {mkdirp: true}, console.error); 

它与以下错误:

 { Error: EPERM: operation not permitted, rename 'E:\tmp\dir\sub' -> 'E:\tmp\dir' at Error (native) errno: -4048, code: 'EPERM', syscall: 'rename', path: 'E:\\tmp\\dir\\sub', dest: 'E:\\tmp\\dir' } 

使用fs-extra而不是mv:

 var fs = require('fs-extra'); var extractPath = 'E:\\tmp\\dir'; fs.move(extractPath + "\\sub", extractPath, console.error); 

在移动之前,我的文件结构是这样的:

 E:\tmp\dir > sub > doc.txt 

而这样的动作之后,

 E:\tmp\dir > doc.txt 

更新:

虽然上面的工作在Windows上,但是在Linux上,即使使用fs-extra也会得到相同的错误。 下面是一个手动修复,通过单独移动子目录的每个孩子到父母。 如果小孩移动失败,则会将其他任何成功的移动回复到子目录中的原始位置。

 var fs = require('fs-extra') var Promise = require('promise'); var path = require('path'); var promiseAllWait = function(promises) { // this is the same as Promise.all(), except that it will wait for all promises to fulfill before rejecting var all_promises = []; for(var i_promise=0; i_promise < promises.length; i_promise++) { all_promises.push( promises[i_promise] .then(function(res) { return { res: res }; }).catch(function(err) { return { err: err }; }) ); } return Promise.all(all_promises) .then(function(results) { return new Promise(function(resolve, reject) { var is_failure = false; var i_result; for(i_result=0; i_result < results.length; i_result++) { if (results[i_result].err) { is_failure = true; break; } else { results[i_result] = results[i_result].res; } } if (is_failure) { reject( results[i_result].err ); } else { resolve(results); } }); }); }; var movePromiser = function(from, to, records) { return fs.move(from, to) .then(function() { records.push( {from: from, to: to} ); }); }; var moveDir = function(from_dir, to_dir) { return fs.readdir(from_dir) .then(function(children) { return fs.ensureDir(to_dir) .then(function() { var move_promises = []; var moved_records = []; var child; for(var i_child=0; i_child < children.length; i_child++) { child = children[i_child]; move_promises.push(movePromiser( path.join(from_dir, child), path.join(to_dir, child), moved_records )); } return promiseAllWait(move_promises) .catch(function(err) { var undo_move_promises = []; for(var i_moved_record=0; i_moved_record < moved_records.length; i_moved_record++) { undo_move_promises.push( fs.move(moved_records[i_moved_record].to, moved_records[i_moved_record].from) ); } return promiseAllWait(undo_move_promises) .then(function() { throw err; }); }); }).then(function() { return fs.rmdir(from_dir); }); }); };