Comment déplacer des fichiers dans node.js?

151

Comment puis-je déplacer des fichiers (comme le shell de commande mv) sur node.js? Existe-t-il une méthode pour cela ou dois-je lire un fichier, écrire dans un nouveau fichier et supprimer l'ancien fichier?

rizidoro
la source

Réponses:

157

Selon le commentaire seppo0010, j'ai utilisé la fonction de changement de nom pour ce faire.

http://nodejs.org/docs/latest/api/fs.html#fs_fs_rename_oldpath_newpath_callback

fs.rename (oldPath, newPath, rappel)

Ajouté dans: v0.0.2

oldPath <String> | <Buffer>
newPath <String> | <Buffer>
callback <Function>

Renommer asynchrone (2). Aucun argument autre qu'une exception possible n'est donné au rappel d'achèvement.

rizidoro
la source
5
Pour ceux qui se demandent où est allé le commentaire de @ seppo0010: c'était sur ma réponse, que j'ai supprimée et postée en commentaire sur l'OP.
Matt Ball
6
Cela ne fonctionnera pas si vous traversez des partitions ou si vous utilisez un système de fichiers virtuel ne prenant pas en charge le déplacement de fichiers. Vous feriez mieux d'utiliser cette solution avec une copie de secours
Flavien Volken
La 3ème réponse par "Hani" a un exemple de code!
Nathan le
47

Cet exemple tiré de: Node.js en action

Une fonction move () qui renomme, si possible, ou revient à la copie

var fs = require('fs');

module.exports = function move(oldPath, newPath, callback) {

    fs.rename(oldPath, newPath, function (err) {
        if (err) {
            if (err.code === 'EXDEV') {
                copy();
            } else {
                callback(err);
            }
            return;
        }
        callback();
    });

    function copy() {
        var readStream = fs.createReadStream(oldPath);
        var writeStream = fs.createWriteStream(newPath);

        readStream.on('error', callback);
        writeStream.on('error', callback);

        readStream.on('close', function () {
            fs.unlink(oldPath, callback);
        });

        readStream.pipe(writeStream);
    }
}
Teoman Shipahi
la source
3
A travaillé comme un charme. Merci! Si je peux ajouter un peu: «déplacer» pourrait être un meilleur nom lorsqu'il dissocie oldPath.
Jokester
La fonction copy () est OK dans ce cas, mais si quelqu'un veut l'envelopper dans un objet Promise, veuillez consulter ma "réponse" ci-dessous ou garder à l'esprit de résoudre la promesse lors de l'événement "close" sur le flux d'écriture, pas sur le flux de lecture.
Jem
Cela ressemble à quelque chose qui fonctionnera pour mes besoins, mais je ne sais pas comment utiliser le style module.exports = function {}. est-ce que je copie ce code dans mon application elle-même où j'ai déjà var fs = require ('fs'); puis appelez fs.move (oldFile, newFile, function (err) {....}) au lieu de fs.rename?
Curious101
@ Curious101 Vous pouvez mettre ceci dans un fichier comme filemove.js et l'importer comme var filemove = require ('filemove'); puis utilisez-le comme filemove (...);
Teoman shipahi
Merci @Teomanshipahi. Dans ce cas, je peux ajouter à mylibrary.js et l'utiliser à partir de là. Je pensais que c'était une méthode bien connue pour ajouter des méthodes de prototype afin qu'elle devienne disponible dans l'objet lui-même.
Curious101
35

Utilisation native de nodejs

var fs = require('fs')

var oldPath = 'old/path/file.txt'
var newPath = 'new/path/file.txt'

fs.rename(oldPath, newPath, function (err) {
  if (err) throw err
  console.log('Successfully renamed - AKA moved!')
})

(REMARQUE: "Cela ne fonctionnera pas si vous traversez des partitions ou si vous utilisez un système de fichiers virtuel ne prenant pas en charge le déplacement des fichiers. [...]" - Flavien Volken 2 septembre 15 à 12:50 ")

Hani
la source
30

Utilisez le module de nœud mv qui essaiera d'abord de faire un fs.rename, puis de revenir à la copie puis à la dissociation.

andrewrk
la source
A bien fonctionné pour les exigences simples pour déplacer un fichier.
arcseldon
1
andrewrk semble être l'auteur de ce mvmodule de nœud. J'aime utiliser npm pour installer; npm install mv --save-dev; voici le lien npm
The Red Pea
4
En quoi est-ce une dépendance au développement? L'application n'a-t-elle pas besoin de mv pour fonctionner?
jgr0
18

util.pump est obsolète dans le nœud 0.10 et génère un message d'avertissement

 util.pump() is deprecated. Use readableStream.pipe() instead

La solution pour copier des fichiers à l'aide de flux est donc:

var source = fs.createReadStream('/path/to/source');
var dest = fs.createWriteStream('/path/to/dest');

source.pipe(dest);
source.on('end', function() { /* copied */ });
source.on('error', function(err) { /* error */ });
mort
la source
2
C'est la bonne façon de copier / déplacer un fichier qui se trouve sur deux partitions différentes. Je vous remercie!
slickplaid
9

Utilisation de la fonction renommer:

fs.rename(getFileName, __dirname + '/new_folder/' + getFileName); 

getFilename = file.extension (old path)
__dirname + '/new_folder/' + getFileName

en supposant que vous souhaitez conserver le nom de fichier inchangé.

Iulia
la source
4
Attention, cela ne fonctionnera pas si vous essayez de renommer le fichier entre différentes partitions, ni sur certains systèmes de fichiers virtuels (comme docker par exemple)
Flavien Volken
8

Le fs-extramodule vous permet de faire cela avec sa move()méthode. Je l'ai déjà implémenté et cela fonctionne bien si vous souhaitez déplacer complètement un fichier d'un répertoire à un autre - ie. suppression du fichier du répertoire source. Devrait fonctionner pour la plupart des cas basiques.

var fs = require('fs-extra')

fs.move('/tmp/somefile', '/tmp/does/not/exist/yet/somefile', function (err) {
 if (err) return console.error(err)
 console.log("success!")
})
Mikeym
la source
5

Voici un exemple utilisant util.pump, à partir de >> Comment déplacer le fichier a vers une partition ou un périphérique différent dans Node.js?

var fs = require('fs'),
    util = require('util');

var is = fs.createReadStream('source_file')
var os = fs.createWriteStream('destination_file');

util.pump(is, os, function() {
    fs.unlinkSync('source_file');
});
alessioalex
la source
20
Il est à noter que vous ne devez le faire que lorsque vous déplacez des fichiers sur des volumes. Sinon, vous pouvez simplement utiliser fs.rename()(dans un volume renommer un fichier et le déplacer, c'est la même chose).
s4y
4
util.pump est obsolète.
andrewrk
Est-il possible de déplacer un fichier d'une machine locale vers un serveur?
Hulk1991
Non, vous devez utiliser autre chose pour cela (comme utiliser FTP, HTTP ou un autre protocole).
alessioalex
4

Utilisation des promesses pour les versions de Node supérieures à 8.0.0:

const {promisify} = require('util');
const fs = require('fs');
const {join} = require('path');
const mv = promisify(fs.rename);

const moveThem = async () => {
  // Move file ./bar/foo.js to ./baz/qux.js
  const original = join(__dirname, 'bar/foo.js');
  const target = join(__dirname, 'baz/qux.js'); 
  await mv(original, target);
}

moveThem();
vorillaz
la source
3
Juste un mot d'avertissement fs.renamene fonctionne pas si vous êtes dans un environnement Docker avec des volumes.
Atul Yadav
Ajoutez une asyncdéclaration à la moveThemfonction.
H_I
3

Juste mes 2 cents comme indiqué dans la réponse ci - dessus : La méthode copy () ne doit pas être utilisée telle quelle pour copier des fichiers sans un léger ajustement:

function copy(callback) {
    var readStream = fs.createReadStream(oldPath);
    var writeStream = fs.createWriteStream(newPath);

    readStream.on('error', callback);
    writeStream.on('error', callback);

    // Do not callback() upon "close" event on the readStream
    // readStream.on('close', function () {
    // Do instead upon "close" on the writeStream
    writeStream.on('close', function () {
        callback();
    });

    readStream.pipe(writeStream);
}

La fonction de copie enveloppée dans une promesse:

function copy(oldPath, newPath) {
  return new Promise((resolve, reject) => {
    const readStream = fs.createReadStream(oldPath);
    const writeStream = fs.createWriteStream(newPath);

    readStream.on('error', err => reject(err));
    writeStream.on('error', err => reject(err));

    writeStream.on('close', function() {
      resolve();
    });

    readStream.pipe(writeStream);
  })

Cependant, gardez à l'esprit que le système de fichiers peut se bloquer si le dossier cible n'existe pas.

Jem
la source
3

Je séparerais toutes les fonctions concernées (c. -à rename, copy, unlink) de l'autre pour gagner en flexibilité et tout promisify, bien sûr:

const renameFile = (path, newPath) => 
  new Promise((res, rej) => {
    fs.rename(path, newPath, (err, data) =>
      err
        ? rej(err)
        : res(data));
  });

const copyFile = (path, newPath, flags) =>
  new Promise((res, rej) => {
    const readStream = fs.createReadStream(path),
      writeStream = fs.createWriteStream(newPath, {flags});

    readStream.on("error", rej);
    writeStream.on("error", rej);
    writeStream.on("finish", res);
    readStream.pipe(writeStream);
  });

const unlinkFile = path => 
  new Promise((res, rej) => {
    fs.unlink(path, (err, data) =>
      err
        ? rej(err)
        : res(data));
  });

const moveFile = (path, newPath, flags) =>
  renameFile(path, newPath)
    .catch(e => {
      if (e.code !== "EXDEV")
        throw new e;

      else
        return copyFile(path, newPath, flags)
          .then(() => unlinkFile(path));
    });

moveFile est juste une fonction pratique et nous pouvons appliquer les fonctions séparément, lorsque, par exemple, nous avons besoin d'une gestion des exceptions plus fine.


la source
2

Shelljs est une solution très pratique.

commande: mv ([options,] source, destination)

Options disponibles:

-f: force (comportement par défaut)

-n: pour éviter l'écrasement

const shell = require('shelljs');
const status = shell.mv('README.md', '/home/my-dir');
if(status.stderr)  console.log(status.stderr);
else console.log('File moved!');
Prayag k
la source
1

il s'agit d'une répétition de la réponse de teoman shipahi avec un nom légèrement moins ambigu et suivant le principe de conception consistant à définir le code avant d'essayer de l'appeler. (Bien que node vous permette de faire autrement, ce n'est pas une bonne pratique de mettre la charrue avant les boeufs.)

function rename_or_copy_and_delete (oldPath, newPath, callback) {

    function copy_and_delete () {
        var readStream = fs.createReadStream(oldPath);
        var writeStream = fs.createWriteStream(newPath);

        readStream.on('error', callback);
        writeStream.on('error', callback);
        readStream.on('close', 
              function () {
                fs.unlink(oldPath, callback);
              }
        );

        readStream.pipe(writeStream);
    }

    fs.rename(oldPath, newPath, 
        function (err) {
          if (err) {
              if (err.code === 'EXDEV') {
                  copy_and_delete();
              } else {
                  callback(err);
              }
              return;// << both cases (err/copy_and_delete)
          }
          callback();
        }
    );
}
non synchronisé
la source
0

À l'aide de l'URL ci-dessous, vous pouvez copier ou déplacer votre fichier Source ACTUELLE vers la source de destination

https://coursesweb.net/nodejs/move-copy-file

/*********Moves the $file to $dir2 Start *********/
var moveFile = (file, dir2)=>{
  //include the fs, path modules
  var fs = require('fs');
  var path = require('path');

  //gets file name and adds it to dir2
  var f = path.basename(file);
  var dest = path.resolve(dir2, f);

  fs.rename(file, dest, (err)=>{
    if(err) throw err;
    else console.log('Successfully moved');
  });
};

//move file1.htm from 'test/' to 'test/dir_1/'
moveFile('./test/file1.htm', './test/dir_1/');
/*********Moves the $file to $dir2 END *********/

/*********copy the $file to $dir2 Start *********/
var copyFile = (file, dir2)=>{
  //include the fs, path modules
  var fs = require('fs');
  var path = require('path');

  //gets file name and adds it to dir2
  var f = path.basename(file);
  var source = fs.createReadStream(file);
  var dest = fs.createWriteStream(path.resolve(dir2, f));

  source.pipe(dest);
  source.on('end', function() { console.log('Succesfully copied'); });
  source.on('error', function(err) { console.log(err); });
};

//example, copy file1.htm from 'test/dir_1/' to 'test/'
copyFile('./test/dir_1/file1.htm', './test/');
/*********copy the $file to $dir2 END *********/

Abdullah Pariyani
la source
-6

Vous pouvez utiliser le move-filepackage npm:

Installez d'abord le package:

$ npm install move-file

Usage:

const moveFile = require('move-file');

// moveFile Returns a Promise that resolves when the file has been moved
moveFile('source/unicorn.png', 'destination/unicorn.png')
  .then(() => {/* Handle success */})
  .catch((err) => {/* Handle failure */});

// Or use async/await
(async () => {
    try {
      await moveFile('source/unicorn.png', 'destination/unicorn.png');
      console.log('The file has been moved');
    } catch (err) {
      // Handle failure
      console.error(err);
    }
})();
Paridhi shah
la source
Réponse courte et intelligente, bonne @paridhishah
Abdullah Pariyani
2
C'est un appel à une fonction qui n'a pas encore été créée, donc ne fera que lancer une erreur.
Steve Carey le