Skip to content

Instantly share code, notes, and snippets.

@nlaplante
Last active December 23, 2015 09:59
Show Gist options
  • Save nlaplante/6617953 to your computer and use it in GitHub Desktop.
Save nlaplante/6617953 to your computer and use it in GitHub Desktop.
node.js implementation to move files avoiding EXDEV errors when moving files across different devices
'use strict';
var fs = require('fs'),
q = require('q');
/**
* Move a file from src to dest, avoiding cross-device rename failures.
* This method will first try fs.rename and call the supplied callback if it succeeds. Otherwise
* it will pump the conent of src into dest and unlink src upon completion.
*
* This might take a little more time than a single fs.rename, but it avoids error when
* trying to rename files from one device to the other.
*
* @param src {String} absolute path to source file
* @param dest {String} absolute path to destination file
* @param cb {Function} callback to execute upon success or failure
*/
exports.move = function (src, dest, cb) {
var renameDeferred = q.defer();
fs.rename(src, dest, function (err) {
if (err) {
renameDeferred.reject(err);
}
else {
renameDeferred.resolve();
}
});
renameDeferred.promise.then(function () {
// rename worked
return cb(null);
}, function (err) {
console.warn('io.move: standard rename failed, trying stream pipe... (' + err + ')');
// rename didn't work, try pumping
var is = fs.createReadStream(src),
os = fs.createWriteStream(dest);
is.pipe(os);
is.on('end', function () {
fs.unlinkSync(src);
cb(null);
});
is.on('error', function (err) {
return cb(err);
});
os.on('error', function (err) {
return cb(err);
})
});
};
@nlaplante
Copy link
Author

Depends on q (npm install q)

@cmoon2000
Copy link

thank you! It works on me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment