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");

2voto

Emilio Grisolía Points 676

Si vous êtes sous Linux, et que la performance n'est pas un problème, vous pouvez utiliser la commande exec de la fonction child_process pour exécuter une commande Bash :

const { exec } = require('child_process');
exec('cp -r source dest', (error, stdout, stderr) => {...});

Dans certains cas, j'ai trouvé cette solution plus propre que le téléchargement d'un module complet ou même l'utilisation de la fonction fs module.

1voto

Ce code fonctionnera très bien, en copiant récursivement n'importe quel dossier vers n'importe quel emplacement. Mais il est réservé à Windows.

var child = require("child_process");
function copySync(from, to){
    from = from.replace(/\//gim, "\\");
    to = to.replace(/\//gim, "\\");
    child.exec("xcopy /y /q \"" + from + "\\*\" \"" + to + "\\\"");
}

Il fonctionne parfaitement pour mon jeu en mode texte pour la création de nouveaux joueurs.

1voto

Ahsan.Amin Points 226

Si vous voulez copier tout le contenu du répertoire source de manière récursive, vous devez passer le paramètre recursive comme true et try catch est documenté par fs-extra de la façon suivante sync

Comme fs-extra est un remplacement complet de fs de sorte que vous n'avez pas besoin d'importer le module de base

const fs = require('fs-extra');
let sourceDir = '/tmp/src_dir';
let destDir = '/tmp/dest_dir';
try {
  fs.copySync(sourceDir, destDir, { recursive: true })
  console.log('success!')
} catch (err) {
  console.error(err)
}

1voto

stpoa Points 2136

Version de TypeScript

async function copyDir(source: string, destination: string): Promise<any> {
  const directoryEntries = await readdir(source, { withFileTypes: true });
  await mkdir(destination, { recursive: true });

  return Promise.all(
    directoryEntries.map(async (entry) => {
      const sourcePath = path.join(source, entry.name);
      const destinationPath = path.join(destination, entry.name);

      return entry.isDirectory()
        ? copyDir(sourcePath, destinationPath)
        : copyFile(sourcePath, destinationPath);
    })
  );
}

1voto

Flavio Del Grosso Points 197

Cela pourrait être une solution possible en utilisant la fonction de générateur asynchrone et en itérant avec for await boucle. Cette solution inclut la possibilité de filtrer certains répertoires en les passant comme troisième argument facultatif du tableau.

import path from 'path';
import { readdir, copy } from 'fs-extra';

async function* getCopyableFiles(srcDir: string, destDir: string, excludedFolders?: string[]): AsyncGenerator<string> {
  const directoryEntries = await readdir(srcDir, { withFileTypes: true });
  for (const entry of directoryEntries) {
    const fileName = entry.name;
    const filePath = path.join(srcDir, fileName);
    if (entry.isDirectory()) {
      if (!excludedFolders?.includes(filePath)) {
        yield* getCopyableFiles(filePath, path.join(destDir, fileName), excludedFolders);
      }
    } else {
      yield filePath;
    }
  }
}

Ensuite :

for await (const filePath of getCopyableFiles(path1, path2, ['dir1', 'dir2'])) {
   await copy(filePath, filePath.replace(path1, path2));
}

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