¿Cómo muevo archivos en node.js?


151

¿Cómo puedo mover archivos (como el comando mv shell) en node.js? ¿Hay algún método para eso o debería leer un archivo, escribir en un archivo nuevo y eliminar un archivo anterior?

Respuestas:


157

Según el comentario seppo0010, utilicé la función de cambio de nombre para hacer eso.

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

fs.rename (oldPath, newPath, callback)

Añadido en: v0.0.2

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

Cambio de nombre asincrónico (2). No hay argumentos distintos de una posible excepción para la devolución de llamada de finalización.


55
Para aquellos que se preguntan dónde fue el comentario de @ seppo0010: fue en mi respuesta, que eliminé y publiqué como un comentario en el OP.
Matt Ball

66
Esto no funcionará si cruza particiones o utiliza un sistema de archivos virtual que no admite archivos en movimiento. Es mejor que use esta solución con una copia de respaldo
Flavien Volken

¡La tercera respuesta de "Hani" tiene un código de ejemplo!
Nathan

47

Este ejemplo tomado de: Node.js en acción

Una función move () que cambia el nombre, si es posible, o vuelve a copiar

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

3
Trabajado como un encanto. ¡Gracias! Si puedo agregar un poco: 'mover' podría ser un mejor nombre cuando desvincula oldPath.
Jokester

La función copy () está bien en este caso, pero si alguien quiere envolverla dentro de un objeto Promise, vea mi "respuesta" a continuación o tenga en cuenta para resolver la promesa sobre el evento "close" en la secuencia de escritura, no en la secuencia de lectura.
Jem

Esto parece algo que funcionará para mis necesidades, sin embargo, no sé cómo usar el estilo module.exports = function {}. copio este código en mi propia aplicación donde ya tengo var fs = require ('fs'); y luego llame a fs.move (oldFile, newFile, function (err) {....}) en lugar de fs.rename?
Curioso101

@ Curious101 Puede poner esto en un archivo como filemove.js e importarlo como var filemove = require ('filemove'); luego úsalo como filemove (...);
Teoman shipahi

Gracias @Teomanshipahi. En ese caso, puedo agregar a mylibrary.js y usarlo desde allí. Pensé que este era un método bien conocido de agregar métodos prototipo para que esté disponible en el objeto mismo.
Curioso101

35

Usar nodejs de forma nativa

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!')
})

(NOTA: "Esto no funcionará si está cruzando particiones o está utilizando un sistema de archivos virtual que no admite archivos en movimiento." [...] - Flavien Volken 2 de septiembre de 2015 a las 12:50 ")


30

Utilice el módulo de nodo mv , que primero intentará hacer una fs.renamecopia de seguridad y luego volver a copiar y luego desvincular.


Funcionó bien para los requisitos simples para mover un archivo.
arcseldon

1
andrewrk parece ser el autor de este mvmódulo de nodo. Me gusta usar npm para instalar; npm install mv --save-dev; aquí está el enlace npm
The Red Pea

3
¿Cómo es esto una dependencia de desarrollo? ¿La aplicación no requiere mv para funcionar?
jgr0

17

util.pump está en desuso en el nodo 0.10 y genera un mensaje de advertencia

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

Entonces, la solución para copiar archivos usando secuencias es:

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 */ });

2
Esta es la forma correcta de copiar / mover un archivo que está en dos particiones diferentes. ¡Gracias!
slickplaid

9

Usando la función renombrar:

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

dónde

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

suponiendo que desea mantener el nombre del archivo sin cambios.


44
Tenga cuidado de que esto no funcione si intenta cambiar el nombre del archivo entre diferentes particiones, ni en algunos sistemas de archivos virtuales (como Docker, por ejemplo)
Flavien Volken

8

El fs-extramódulo le permite hacer esto con su move()método. Ya lo implementé y funciona bien si desea mover completamente un archivo de un directorio a otro, es decir. eliminando el archivo del directorio fuente. Debería funcionar para la mayoría de los casos básicos.

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!")
})

5

Aquí hay un ejemplo usando util.pump, desde >> ¿Cómo muevo el archivo a a una partición o dispositivo diferente en 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');
});

20
Vale la pena señalar que solo tiene que hacer esto al mover archivos a través de volúmenes. De lo contrario, solo puede usar fs.rename()(dentro de un volumen, cambiar el nombre de un archivo y moverlo es lo mismo).
s4y

44
util.pump está en desuso.
andrewrk


¿Es posible mover el archivo de la máquina local al servidor?
Hulk1991

No, necesitas usar algo más para eso (como usar FTP, HTTP u otro protocolo).
alessioalex

4

Uso de promesas para versiones de nodo superiores a 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();

3
Solo una palabra de precaución fs.renameno funciona si está en un entorno Docker con volúmenes.
Atul Yadav

Agregue una asyncdeclaración a la moveThemfunción.
H_I

3

Solo mis 2 centavos como se indica en la respuesta anterior : el método copy () no debe usarse tal cual para copiar archivos sin un ligero ajuste:

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 función de copia envuelta en una Promesa:

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

Sin embargo, tenga en cuenta que el sistema de archivos podría fallar si la carpeta de destino no existe.


3

Me gustaría separar todas las funciones implicadas (es decir rename, copy, unlink) entre sí para ganar flexibilidad y promisify todo, por supuesto:

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 es solo una función de conveniencia y podemos aplicar las funciones por separado, cuando, por ejemplo, necesitamos un manejo de excepciones más fino.


2

Shelljs es una solución muy útil.

comando: mv ([opciones,] origen, destino)

Opciones Disponibles:

-f: fuerza (comportamiento predeterminado)

-n: para evitar sobrescribir

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!');

1

Esta es una repetición de la respuesta de Teoman Shipahi con un nombre un poco menos ambiguo, y siguiendo el principio de diseño de la definición del código antes de intentar llamarlo. (Si bien el nodo le permite hacer lo contrario, no es una buena práctica poner el carro delante del caballo).

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();
        }
    );
}

0

Con la ayuda de la URL a continuación, puede copiar o mover su archivo Origen ACTUAL al Origen de destino

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 *********/



-6

Puede usar el move-filepaquete npm:

Primero instale el paquete:

$ npm install move-file

Uso:

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);
    }
})();

Respuesta corta e inteligente, buena @paridhishah
Abdullah Pariyani

2
Esa es una llamada a una función que aún no se ha creado, por lo que simplemente arrojará un error.
Steve Carey
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.