I am using copy method of fs-extra to copy files from a source to destination. My use case is to create a copy of the file with a name like if a file of the same name exists in the destination. The copy method of fs-extra module overwrites the destination file.
Asked
Active
Viewed 5,338 times
1
-
What should happen when the file already exists? – nijm Jul 03 '18 at 16:05
-
@nijm A new file should be created with the name
– Ravi Kukreja Jul 04 '18 at 08:14
2 Answers
2
You could try something like this:
const fs = require('fs-extra');
async function copy(src, dest) {
try {
await fs.copy(src, dest, { overwrite: false, errorOnExist: true });
return true;
} catch (error) {
if (error.message.includes('already exists')) {
return false;
}
throw error;
}
}
async function copyWithoutOverwrite(src, dest, maxAttempts) {
try {
if (!await copy(src, dest)); {
for (let i = 1; i <= maxAttempts; i++) {
if (await copy(src, `${dest}_copy${i}`)) {
return;
}
}
}
} catch (error) {
console.error(error);
}
}
const src = '/tmp/testfile';
const dest = '/tmp/mynewfile';
const maxAttempts = 10;
copyWithoutOverwrite(src, dest, maxAttempts);

nijm
- 2,158
- 12
- 28
-
Also see overwrite property in the documentation :-) https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy-sync.md – ow3n Feb 08 '22 at 00:32
1
So basically you need to implement custom copy procedure, that you can interrupt and alter at any moment. fs-jetpack does this very well.
const pathUtil = require("path");
const jetpack = require("fs-jetpack");
const src = jetpack.cwd("path/to/source/folder");
const dst = jetpack.cwd("path/to/destination/folder");
const findUnusedPath = path => {
const pathDir = pathUtil.dirname(path);
const extension = pathUtil.extname(path);
const fileName = pathUtil.basename(path, extension);
const pathCandidate = pathUtil.join(pathDir, `${fileName}-duplicate${extension}`);
if (dst.exists(pathCandidate)) {
// Will just add "-duplicate-duplicate-duplicate..." to name
// of the file until finds unused name.
return findUnusedPath(pathCandidate);
} else {
return pathCandidate;
}
};
// Iterate over all files in source directory and manually decide
// where to put them in destination directory.
src.find().forEach(filePath => {
const content = src.read(filePath, "buffer");
let destPath = filePath;
if (dst.exists(destPath)) {
destPath = findUnusedPath(destPath);
}
dst.write(destPath, content);
});
Here using file read/write instead of copy, because it's faster in this particular case. Copy needs to check first what the path is: directory or file. If we already know it is a file there is no need for this extra work.

Jakub Szwacz
- 51
- 2