Come posso spostare i file in node.js?


151

Come posso spostare i file (come la shell dei comandi mv) su node.js? Esiste un metodo per questo o dovrei leggere un file, scrivere in un nuovo file e rimuovere il file precedente?

Risposte:


157

Secondo il commento di seppo0010, ho usato la funzione di rinomina per farlo.

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

fs.rename (oldPath, newPath, callback)

Aggiunto in: v0.0.2

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

Rinominare asincrono (2). Nessun argomento diverso da una possibile eccezione viene fornito al callback di completamento.


5
Per chi si chiede dove sia andato il commento di @ seppo0010: era sulla mia risposta, che ho eliminato e pubblicato come commento sul PO.
Matt Ball,

6
Questo non funzionerà se si attraversano partizioni o si utilizza un filesystem virtuale che non supporta lo spostamento di file. Faresti meglio a usare questa soluzione con un fallback della copia
Flavien Volken,

La terza risposta di "Hani" ha un codice di esempio!
Nathan il

47

Questo esempio è tratto da: Node.js in Azione

Una funzione move () che rinomina, se possibile, o ricade nella copia

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
Ha funzionato come un fascino. Grazie! Se posso aggiungere un po ':' move 'potrebbe essere un nome migliore quando scollega oldPath.
Jokester,

La funzione copy () è OK in questo caso, ma se qualcuno intende avvolgerlo all'interno di un oggetto Promise, vedere la mia "risposta" di seguito o tenere a mente per risolvere la promessa sull'evento "close" sul flusso di scrittura, non sul flusso di lettura.
Jem

Sembra qualcosa che funzioni per le mie esigenze, tuttavia non so come usare lo stile module.exports = function {}. copio questo codice nella mia stessa app dove ho già var fs = request ('fs'); e quindi chiama fs.move (oldFile, newFile, function (err) {....}) invece di fs.rename?
Curious101,

@ Curious101 Puoi inserirlo in un file come filemove.js e importarlo come var filemove = require ('filemove'); quindi usalo come filemove (...);
Teoman Shipahi

Grazie @Teomanshipahi. In tal caso, posso aggiungere a mylibrary.js e usarlo da lì. Ho pensato che questo fosse un metodo ben noto per aggiungere metodi prototipo in modo da renderlo disponibile nell'oggetto stesso.
Curious101

35

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

(NOTA: "Questo non funzionerà se si attraversano partizioni o si utilizza un filesystem virtuale che non supporta lo spostamento di file. [...]" - Flavien Volken 2 settembre 15 alle 12:50 ")


30

Utilizzare il modulo nodo mv che proverà prima a fare un, fs.renamequindi fallback alla copia e quindi al scollegamento.


Ha funzionato bene per i semplici requisiti per spostare un file.
ArcSeldon,

1
andrewrk sembra essere l'autore di questo mvmodulo nodo. Mi piace usare npm per installare; npm install mv --save-dev; ecco il link npm
The Red Pea,

3
In che modo questa è una dipendenza da sviluppo? L'app non richiede mv per funzionare?
jgr0

17

util.pump è obsoleto nel nodo 0.10 e genera un messaggio di avviso

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

Quindi la soluzione per copiare i file usando gli stream è:

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
Questo è il modo corretto di copiare / spostare un file che si trova su due diverse partizioni. Grazie!
slickplaid,

9

Utilizzando la funzione di rinomina:

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

dove

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

supponendo che si desidera mantenere invariato il nome del file.


4
Fai attenzione che non funzionerà se provi a rinominare il file tra diverse partizioni, né su alcuni file system virtuali (come ad esempio la finestra mobile)
Flavien Volken

8

Il fs-extramodulo ti consente di farlo con il suo move()metodo. L'ho già implementato e funziona bene se si desidera spostare completamente un file da una directory all'altra, ad es. rimuovendo il file dalla directory di origine. Dovrebbe funzionare per la maggior parte dei casi di base.

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

Ecco un esempio usando util.pump, da >> Come posso spostare il file a in una partizione o dispositivo diverso in 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 notare che è necessario farlo solo quando si spostano i file su più volumi. Altrimenti, puoi semplicemente usare fs.rename()(all'interno di un volume rinominare un file e spostarlo sono la stessa cosa).
s4y

4
util.pump è obsoleto.
Andrewrk,


È possibile spostare file dal computer locale al server?
Hulk1991

No, devi usare qualcos'altro per questo (come usare FTP, HTTP o un altro protocollo).
alessioalex,

4

Utilizzo delle promesse per le versioni di Node successive alla 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 un avvertimento fs.renamenon funziona se ci si trova in un ambiente Docker con volumi.
Atul Yadav,

Aggiungi una asyncdichiarazione alla moveThemfunzione.
H_I

3

Solo i miei 2 centesimi come indicato nella risposta sopra : il metodo copy () non dovrebbe essere usato così com'è per copiare file senza una leggera regolazione:

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 funzione di copia racchiusa in una promessa:

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

Tuttavia, tieni presente che il filesystem potrebbe bloccarsi se la cartella di destinazione non esiste.


3

Vorrei separare tutte le funzioni coinvolte (ad esempio rename, copy, unlink) gli uni dagli altri per ottenere flessibilità e promisify tutto, naturalmente:

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 è solo una funzione di convenienza e possiamo applicare le funzioni separatamente, quando, ad esempio, abbiamo bisogno di una gestione delle eccezioni più precisa.


2

Shelljs è una soluzione molto utile.

comando: mv ([opzioni,] sorgente, destinazione)

Opzioni disponibili:

-f: force (comportamento predefinito)

-n: per impedire la sovrascrittura

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

questa è una rivisitazione della risposta di Teoman Shipahi con un nome leggermente meno ambiguo, e seguendo il principio di progettazione del codice di definizione prima di tentare di chiamarlo. (Mentre il nodo ti consente di fare diversamente, non è una buona pratica mettere il carrello davanti al cavallo.)

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 l'aiuto dell'URL seguente, puoi copiare o spostare il tuo file CURRENT Source su Destination Source

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

Puoi usare il move-file pacchetto npm:

Innanzitutto installa il pacchetto:

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

Risposta breve e intelligente, buona @paridhishah
Abdullah Pariyani,

2
Questa è una chiamata a una funzione che non è stata ancora creata, quindi genererà semplicemente un errore.
Steve Carey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.