Existe-t-il un moyen plus simple de copier un dossier et tout son contenu sans effectuer manuellement une séquence de fs.readir
, fs.readfile
, fs.writefile
?
Je me demande juste s'il me manque une fonction qui fonctionnerait idéalement comme ceci
fs.copy("/path/to/source/folder","/path/to/destination/folder");
Vous pouvez utiliser ncp module. Je pense que c'est ce dont tu as besoin
Ceci est mon approche pour résoudre ce problème sans aucun module supplémentaire. En utilisant simplement les modules fs
et path
intégrés.
Note: Ceci utilise les fonctions lecture/écriture de fs, donc il ne copie aucune métadonnée (heure de création, etc.). À partir du noeud 8.5, il existe une copyFileSync
fonctions disponibles qui appellent les fonctions de copie du système d'exploitation et, par conséquent, copient également les métadonnées. Je ne les ai pas encore testés, mais cela devrait fonctionner pour les remplacer. (Voir https://nodejs.org/api/fs.html#fs_fs_copyfilesync_src_dest_flags )
var fs = require('fs');
var path = require('path');
function copyFileSync( source, target ) {
var targetFile = target;
//if target is a directory a new file with the same name will be created
if ( fs.existsSync( target ) ) {
if ( fs.lstatSync( target ).isDirectory() ) {
targetFile = path.join( target, path.basename( source ) );
}
}
fs.writeFileSync(targetFile, fs.readFileSync(source));
}
function copyFolderRecursiveSync( source, target ) {
var files = [];
//check if folder needs to be created or integrated
var targetFolder = path.join( target, path.basename( source ) );
if ( !fs.existsSync( targetFolder ) ) {
fs.mkdirSync( targetFolder );
}
//copy
if ( fs.lstatSync( source ).isDirectory() ) {
files = fs.readdirSync( source );
files.forEach( function ( file ) {
var curSource = path.join( source, file );
if ( fs.lstatSync( curSource ).isDirectory() ) {
copyFolderRecursiveSync( curSource, targetFolder );
} else {
copyFileSync( curSource, targetFolder );
}
} );
}
}
Certains modules prennent en charge la copie de dossiers avec leur contenu. Le plus populaire serait clé
// Deep-copy an existing directory
wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');
Une alternative serait node-fs-extra
fs.copy('/tmp/mydir', '/tmp/mynewdir', function (err) {
if (err) {
console.error(err);
} else {
console.log("success!");
}
}); //copies directory, even if it has subdirectories or files
/**
* Look ma, it's cp -R.
* @param {string} src The path to the thing to copy.
* @param {string} dest The path to the new copy.
*/
var copyRecursiveSync = function(src, dest) {
var exists = fs.existsSync(src);
var stats = exists && fs.statSync(src);
var isDirectory = exists && stats.isDirectory();
if (exists && isDirectory) {
fs.mkdirSync(dest);
fs.readdirSync(src).forEach(function(childItemName) {
copyRecursiveSync(path.join(src, childItemName),
path.join(dest, childItemName));
});
} else {
fs.linkSync(src, dest);
}
};
fs-extra
a fonctionné pour moi lorsque ncp
et wrench
ont échoué:
Pour les systèmes d'exploitation Linux/Unix, vous pouvez utiliser la syntaxe Shell
const Shell = require('child_process').execSync ;
const src= `/path/src`;
const dist= `/path/dist`;
Shell(`mkdir -p ${dist}`);
Shell(`cp -r ${src}/* ${dist}`);
C'est tout!
J'ai créé un petit exemple de travail qui copie un dossier source dans un autre dossier de destination en quelques étapes seulement (en fonction de la réponse @ shift66 à l'aide de ncp):
étape 1 - Installer le module ncp:
npm install ncp --save
étape 2 - créer un fichier copy.js (modifiez les variables srcPath et destPath en fonction de vos besoins):
var path = require('path');
var ncp = require('ncp').ncp;
ncp.limit = 16;
var srcPath = path.dirname(require.main.filename); //current folder
var destPath = '/path/to/destination/folder'; //Any destination folder
console.log('Copying files...');
ncp(srcPath, destPath, function (err) {
if (err) {
return console.error(err);
}
console.log('Copying files complete.');
});
étape 3 - courir
node copy.js
le module fs-extra fonctionne à merveille.
Installer fs-extra
$ npm install fs-extra
Voici le programme pour copier le répertoire source dans le répertoire de destination.
// include fs-extra package
var fs = require("fs-extra");
var source = 'folderA'
var destination = 'folderB'
// copy source folder to destination
fs.copy(source, destination, function (err) {
if (err){
console.log('An error occured while copying the folder.')
return console.error(err)
}
console.log('Copy completed!')
});
Références
fs-extra: https://www.npmjs.com/package/fs-extra
Exemple: Tutoriel Node.js - Node.js Copier un dossier
@ mallikarjun-m merci!
fs-extra a fait la chose et il peut même retourner Promise si vous ne fournissez pas de rappel! :)
const path = require('path')
const fs = require('fs-extra')
let source = path.resolve( __dirname, 'folderA')
let destination = path.resolve( __dirname, 'folderB')
fs.copy(source, destination)
.then(() => console.log('Copy completed!'))
.catch( err => {
console.log('An error occured while copying the folder.')
return console.error(err)
})
Comme je ne fais que construire un script de noeud simple, je ne voulais pas que les utilisateurs du script aient besoin d'importer un ensemble de modules externes et de dépendances. Coquille.
Cet extrait de code node.js copie de manière récursive un dossier appelé node-webkit.app dans un dossier appelé build:
child = exec("cp -r node-webkit.app build", function(error, stdout, stderr) {
sys.print("stdout: " + stdout);
sys.print("stderr: " + stderr);
if(error !== null) {
console.log("exec error: " + error);
} else {
}
});
Merci à Lance Pollard de dzone pour m'avoir lancé.
L'extrait de code ci-dessus est limité aux plates-formes Unix telles que Mac OS et Linux, mais une technique similaire peut fonctionner pour Windows.
C'est assez facile avec le noeud 10.
const FSP = require('fs').promises;
async function copyDir(src,dest) {
const entries = await FSP.readdir(src,{withFileTypes:true});
await FSP.mkdir(dest);
for(let entry of entries) {
const srcPath = Path.join(src,entry.name);
const destPath = Path.join(dest,entry.name);
if(entry.isDirectory()) {
await copyDir(srcPath,destPath);
} else {
await FSP.copyFile(srcPath,destPath);
}
}
}
Cela suppose que dest
n'existe pas.
Voici comment je le ferais personnellement:
function copyFolderSync(from, to) {
fs.mkdirSync(to);
fs.readdirSync(from).forEach(element => {
if (fs.lstatSync(path.join(from, element)).isFile()) {
fs.copyFileSync(path.join(from, element), path.join(to, element));
} else {
copyFolderSync(path.join(from, element), path.join(to, element));
}
});
}
fonctionne pour les dossiers et les fichiers
Voici comment j'ai fait:
let fs = require('fs');
let path = require('path');
puis:
let filePath = //your FilePath
let fileList = []
var walkSync = function(filePath, filelist)
{
let files = fs.readdirSync(filePath);
filelist = filelist || [];
files.forEach(function(file)
{
if (fs.statSync(path.join(filePath, file)).isDirectory())
{
filelist = walkSync(path.join(filePath, file), filelist);
}
else
{
filelist.Push(path.join(filePath, file));
}
});
// Ignore hidden files
filelist = filelist.filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
return filelist;
};
Puis appelez la méthode:
This.walkSync(filePath, fileList)
J'ai écrit cette fonction à la fois pour copier (copyFileSync) ou déplacer (renameSync) de manière récursive entre des répertoires:
//copy files
copyDirectoryRecursiveSync(sourceDir, targetDir);
//move files
copyDirectoryRecursiveSync(sourceDir, targetDir, true);
function copyDirectoryRecursiveSync(source, target, move) {
if (!fs.lstatSync(source).isDirectory()) return;
var operation = move ? fs.renameSync : fs.copyFileSync;
fs.readdirSync(source).forEach(function (itemName) {
var sourcePath = path.join(source, itemName);
var targetPath = path.join(target, itemName);
if (fs.lstatSync(sourcePath).isDirectory()) {
fs.mkdirSync(targetPath);
copyDirectoryRecursiveSync(sourcePath, targetDir);
}
else {
operation(sourcePath, targetPath);
}
});}
Ce code fonctionnera très bien, copiant récursivement n'importe quel dossier vers n'importe quel emplacement Windows uniquement.
var child=require("child_process");
function copySync(from,to){
from=from.replace(/\//gim,"\\");
to=to.replace(/\//gim,"\\");
child.exec("xcopy /y /q \""+from+"\\*\" \""+to+"\\\"");
}
Fonctionne parfaitement pour mon jeu basé sur le texte pour la création de nouveaux joueurs.
J'ai essayé fs-extra et copy-dir pour copier le dossier de manière récursive. mais je le veux
Alors j'ai écrit le mien:
//node module for node 8.6+
var path=require("path");
var fs=require("fs");
function copyDirSync(src,dest,options){
var srcPath=path.resolve(src);
var destPath=path.resolve(dest);
if(path.relative(srcPath,destPath).charAt(0)!=".")
throw new Error("dest path must be out of src path");
var settings=Object.assign(Object.create(copyDirSync.options),options);
copyDirSync0(srcPath,destPath,settings);
function copyDirSync0(srcPath,destPath,settings){
var files=fs.readdirSync(srcPath);
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}else if(!fs.lstatSync(destPath).isDirectory()){
if(settings.overwrite)
throw new Error(`Cannot overwrite non-directory '${destPath}' with directory '${srcPath}'.`);
return;
}
files.forEach(function(filename){
var childSrcPath=path.join(srcPath,filename);
var childDestPath=path.join(destPath,filename);
var type=fs.lstatSync(childSrcPath).isDirectory()?"directory":"file";
if(!settings.filter(childSrcPath,type))
return;
if (type=="directory") {
copyDirSync0(childSrcPath,childDestPath,settings);
} else {
fs.copyFileSync(childSrcPath, childDestPath, settings.overwrite?0:fs.constants.COPYFILE_EXCL);
if(!settings.preserveFileDate)
fs.futimesSync(childDestPath,Date.now(),Date.now());
}
});
}
}
copyDirSync.options={
overwrite: true,
preserveFileDate: true,
filter: function(filepath,type){return true;}
};
et une fonction similaire mkdirs, qui est une alternative à mkdirp
function mkdirsSync(dest) {
var destPath=path.resolve(dest);
mkdirsSync0(destPath);
function mkdirsSync0(destPath){
var parentPath=path.dirname(destPath);
if(parentPath==destPath)
throw new Error(`cannot mkdir ${destPath}, invalid root`);
if (!fs.existsSync(destPath)) {
mkdirsSync0(parentPath);
fs.mkdirSync(destPath);
}else if(!fs.lstatSync(destPath).isDirectory()){
throw new Error(`cannot mkdir ${destPath}, a file already exists there`);
}
}
}
L'approche la plus simple pour ce problème consiste à utiliser uniquement les modules 'fs' et 'Path', ainsi que de la logique .....
Tous les fichiers du dossier racine copiés avec le nouveau nom si vous souhaitez simplement définir le numéro de version, par exemple ....................... "" var v = 'Votre répertoire Prénom'"
dans Préfixe du nom de fichier, contenu V ajouté au nom de fichier.
var fs = require('fs-extra');
var path = require('path');
var c = 0;
var i =0 ;
var v = "1.0.2";
var copyCounter = 0;
var directoryCounter = 0;
var directoryMakerCounter = 0;
var recursionCounter = -1;
var Flag = false;
var directoryPath = [] ;
var directoryName = [] ;
var directoryFileName = [];
var fileName;
var directoryNameStorer;
var dc = 0;
var route ;
if (!fs.existsSync(v)){
fs.mkdirSync(v);
}
var basePath = path.join(__dirname, v);
function walk(dir){
fs.readdir(dir, function(err, items) {
items.forEach(function(file){
file = path.resolve(dir, file);
fs.stat(file, function(err, stat){
if(stat && stat.isDirectory()){
directoryNameStorer = path.basename(file);
route = file;
route = route.replace("Gd",v);
directoryFileName[directoryCounter] = route;
directoryPath[directoryCounter] = file;
directoryName[directoryCounter] = directoryNameStorer;
directoryCounter++;
dc++;
if (!fs.existsSync(basePath+"/"+directoryName[directoryMakerCounter])){
fs.mkdirSync(directoryFileName[directoryMakerCounter]);
directoryMakerCounter++;
}
}else{
fileName = path.basename(file);
if(recursionCounter >= 0){
fs.copyFileSync(file, directoryFileName[recursionCounter]+"/"+v+"_"+fileName, err => {
if(err) return console.error(err);
});
copyCounter++;
}else{
fs.copyFileSync(file, v+"/"+v+"_"+fileName, err => {
if(err) return console.error(err);
});
copyCounter++;
}
}
if(copyCounter + dc == items.length && directoryCounter > 0 && recursionCounter < directoryMakerCounter-1){
console.log("COPY COUNTER : "+copyCounter);
console.log("DC COUNTER : "+dc);
recursionCounter++;
dc = 0;
copyCounter = 0;
console.log("ITEM DOT LENGTH : "+items.length);
console.log("RECURSION COUNTER : "+recursionCounter);
console.log("DIRECOTRY MAKER COUNTER : "+directoryMakerCounter);
console.log(": START RECURSION : "+directoryPath[recursionCounter]);
walk(directoryPath[recursionCounter]); //recursive call to copy sub-folder
}
})
})
});
}
walk('./Gd', function(err, data){ //Just Pass The Root Directory Which You Want to Copy
if(err) throw err;
console.log("done");
})
ncp
est cool
quoique ...Vous voudrez peut-être/devriez promettre que sa fonction donnerait super cool
. Puisque vous y êtes, ajoutez-le à un fichier tools
pour le réutiliser.
Vous trouverez ci-dessous une version de travail qui s'appelle Async
et utilise Promises
.
index.js
const {copyFolder} = require('./tools/');
return copyFolder(
yourSourcePath,
yourDestinationPath
)
.then(() => {
console.log('-> Backup completed.')
}) .catch((err) => {
console.log("-> [ERR] Could not copy the folder: ", err);
})
tools.js
const ncp = require("ncp");
/**
* Promise Version of ncp.ncp()
*
* This function promisifies ncp.ncp().
* We take the asynchronous function ncp.ncp() with
* callback semantics and derive from it a new function with
* promise semantics.
*/
ncp.ncpAsync = function (sourcePath, destinationPath) {
return new Promise(function (resolve, reject) {
try {
ncp.ncp(sourcePath, destinationPath, function(err){
if (err) reject(err); else resolve();
});
} catch (err) {
reject(err);
}
});
};
/**
* Utility function to copy folders asynchronously using
* the Promise returned by ncp.ncp().
*/
const copyFolder = (sourcePath, destinationPath) => {
return ncp.ncpAsync(sourcePath, destinationPath, function (err) {
if (err) {
return console.error(err);
}
});
}
module.exports.copyFolder = copyFolder;