218 votes

Copier un dossier de façon récursive dans Node.js

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 de manière récursive ?

Je me demande simplement s'il ne me manque pas une fonction qui fonctionnerait idéalement comme ceci :

fs.copy("/path/to/source/folder", "/path/to/destination/folder");

87voto

Simon Zyx Points 101

Voici mon approche pour résoudre ce problème sans modules supplémentaires. Il suffit d'utiliser le module intégré fs et path modules.

Note : Cela utilise les fonctions de lecture/écriture de fs, et ne copie donc pas de méta-données (heure de création, etc.). A partir de Node.js 8.5, il existe une fonction copyFileSync disponible qui appelle les fonctions de copie du système d'exploitation et copie donc aussi les métadonnées. Je ne les ai pas encore testées, mais cela devrait fonctionner de simplement 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 );
            }
        } );
    }
}

81voto

Arya Points 2170

On dirait que ncp et Clé à molette Les deux ne sont plus maintenus. La meilleure option est probablement d'utiliser fs-extra

Le développeur de la clé à molette indique aux utilisateurs d'utiliser fs-extra car il a déprécié sa bibliothèque

copySync & moveSync Ces deux outils copient et déplacent les dossiers, même s'ils contiennent des fichiers ou des sous-dossiers, et vous pouvez facilement déplacer ou copier des fichiers en les utilisant.

const fse = require('fs-extra');

const srcDir = `path/to/file`;
const destDir = `path/to/destination/directory`;

// To copy a folder or file  
fse.copySync(srcDir, destDir, function (err) {
  if (err) {                 ^
    console.error(err);      |___{ overwrite: true } // add if you want to replace existing folder or file with same name
  } else {
    console.log("success!");
  }
});

OU

// To Move a folder or file  
fse.moveSync(srcDir, destDir, function (err) {
  if (err) {                 ^
    console.error(err);      |___{ overwrite: true } // add if you want to replace existing folder or file with same name
  } else {
    console.log("success!");
  }
});

62voto

Lindsey Simon Points 111

Voici une fonction qui copie récursivement un répertoire et son contenu dans un autre répertoire :

const fs = require("fs")
const path = require("path")

/**
 * 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 (isDirectory) {
    fs.mkdirSync(dest);
    fs.readdirSync(src).forEach(function(childItemName) {
      copyRecursiveSync(path.join(src, childItemName),
                        path.join(dest, childItemName));
    });
  } else {
    fs.copyFileSync(src, dest);
  }
};

55voto

zemirco Points 5419

Certains modules permettent de copier des dossiers avec leur contenu. Les plus populaires sont wrench.js :

// Deep-copy an existing directory
wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');

Une alternative serait nœud-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

33voto

C'est ainsi que je procéderais 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));
        }
    });
}

Il fonctionne pour les dossiers et les fichiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X