Bagaimana cara memindahkan file di node.js?

151

Bagaimana saya bisa memindahkan file (seperti shell perintah mv) di node.js? Apakah ada metode untuk itu atau saya harus membaca file, menulis ke file baru dan menghapus file yang lebih lama?

rizidoro
sumber

Jawaban:

157

Menurut komentar seppo0010, saya menggunakan fungsi rename untuk melakukan itu.

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

fs.rename (oldPath, newPath, callback)

Ditambahkan dalam: v0.0.2

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

Ganti nama asinkron (2). Tidak ada argumen selain pengecualian yang mungkin diberikan untuk panggilan balik penyelesaian.

rizidoro
sumber
5
Bagi mereka yang bertanya-tanya ke mana komentar @ seppo0010 pergi: itu adalah jawaban saya, yang saya hapus dan posting sebagai komentar di OP.
Matt Ball
6
Ini tidak akan berfungsi jika Anda melintasi partisi atau menggunakan sistem file virtual yang tidak mendukung memindahkan file. Anda sebaiknya menggunakan solusi ini dengan salinan cadangan
Flavien Volken
Jawaban ketiga oleh "Hani" memiliki kode contoh!
Nathan
47

Contoh ini diambil dari: Node.js dalam Aksi

Bergerak () fungsi yang mengubah nama, jika mungkin, atau kembali ke menyalin

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
sumber
3
Bekerja seperti pesona. Terima kasih! Jika saya dapat menambahkan sedikit: 'move' mungkin nama yang lebih baik ketika itu membatalkan tautan oldPath.
Jokester
Fungsi copy () tidak apa-apa dalam kasus ini, tetapi jika seseorang bermaksud membungkusnya di dalam objek Promise, harap lihat "jawaban" saya di bawah atau ingatlah untuk menyelesaikan janji pada acara "tutup" pada aliran penulisan, tidak pada aliran baca.
Jem
Ini terlihat seperti sesuatu yang sesuai dengan kebutuhan saya, namun saya tidak tahu bagaimana cara menggunakan style module.exports = function {}. cara menyalin kode ini ke aplikasi saya sendiri di mana saya sudah memiliki var fs = butuhkan ('fs'); dan kemudian panggil fs.move (oldFile, newFile, function (err) {....}) alih-alih fs.rename?
Curious101
@ Curious101 Anda dapat meletakkan ini dalam file seperti filemove.js dan mengimpornya seperti var filemove = require ('filemove'); lalu gunakan seperti filemove (...);
Teoman shipahi
Terima kasih @Teomanshipahi. Dalam hal ini saya dapat menambahkan ke mylibrary.js dan menggunakannya dari sana. Saya pikir ini adalah beberapa metode terkenal menambahkan metode prototipe sehingga menjadi tersedia di objek itu sendiri.
Curious101
35

Menggunakan nodejs secara asli

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

(CATATAN: "Ini tidak akan berfungsi jika Anda melintasi partisi atau menggunakan sistem file virtual yang tidak mendukung memindahkan file. [...]" - Flavien Volken 2 Sep 15 'jam 12:50 ")

Hani
sumber
30

Gunakan modul mv node yang pertama kali akan mencoba melakukan fs.renamedan kemudian mundur untuk menyalin dan kemudian membatalkan tautan.

andrewrk
sumber
Bekerja dengan baik untuk persyaratan sederhana untuk memindahkan file.
arcseldon
1
andrewrk tampaknya menjadi penulis mvmodul simpul ini . Saya suka menggunakan npm untuk menginstal; npm install mv --save-dev; inilah tautan npm
The Red Pea
3
Bagaimana ini ketergantungan dev? Bukankah aplikasi membutuhkan mv agar berfungsi?
jgr0
17

util.pump ditinggalkan di simpul 0.10 dan menghasilkan pesan peringatan

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

Jadi solusi untuk menyalin file menggunakan stream adalah:

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 */ });
deadrunk
sumber
2
Ini adalah cara yang tepat untuk menyalin / memindahkan file yang ada di dua partisi berbeda. Terima kasih!
Slickplaid
9

Menggunakan fungsi ganti nama:

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

dimana

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

dengan asumsi bahwa Anda ingin menjaga nama file tidak berubah.

iulia
sumber
4
Hati-hati, ini tidak akan berfungsi jika Anda mencoba mengubah nama file di antara partisi yang berbeda, juga pada beberapa sistem file virtual (seperti buruh pelabuhan misalnya)
Flavien Volken
8

The fs-extramodul memungkinkan Anda untuk melakukan hal ini dengan itu move()metode. Saya sudah menerapkannya dan berfungsi dengan baik jika Anda ingin memindahkan file dari satu direktori ke direktori lainnya - mis. menghapus file dari direktori sumber. Harus bekerja untuk sebagian besar kasus dasar.

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
sumber
5

Berikut ini contoh menggunakan util.pump, dari >> Bagaimana cara memindahkan file a ke partisi atau perangkat lain di 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
sumber
20
Perlu dicatat bahwa Anda hanya perlu melakukan ini saat memindahkan file melintasi volume. Jika tidak, Anda bisa menggunakan fs.rename()(dalam volume mengubah nama file dan memindahkannya adalah hal yang sama).
s4y
4
util.pump sudah usang.
andrewrk
Apakah mungkin untuk memindahkan file dari mesin lokal ke server?
Hulk1991
Tidak, Anda perlu menggunakan sesuatu yang lain untuk itu (seperti menggunakan FTP, HTTP atau protokol lain).
alessioalex
4

Menggunakan janji untuk versi Node yang lebih besar dari 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
sumber
3
Hanya kata hati-hati fs.renametidak berfungsi jika Anda berada di lingkungan Docker dengan volume.
Atul Yadav
Tambahkan asyncdeklarasi ke moveThemfungsi.
H_I
3

Hanya 2 sen saya sebagaimana dinyatakan dalam jawaban di atas : Metode copy () tidak boleh digunakan apa adanya untuk menyalin file tanpa sedikit penyesuaian:

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

Fungsi salin yang dibungkus dalam Janji:

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

Namun, perlu diingat bahwa sistem file mungkin macet jika folder target tidak ada.

Jem
sumber
3

Saya akan memisahkan semua fungsi yang terlibat (yaitu rename, copy, unlink) dari satu sama lain untuk mendapatkan fleksibilitas dan promisify semuanya, tentu saja:

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 hanyalah fungsi kenyamanan dan kita dapat menerapkan fungsi secara terpisah, ketika, misalnya, kita membutuhkan penanganan pengecualian berbutir halus.


sumber
2

Shelljs adalah solusi yang sangat berguna.

perintah: mv ([opsi,] sumber, tujuan)

Pilihan yang tersedia:

-f: force (perilaku default)

-n: untuk mencegah penulisan ulang

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
sumber
1

ini adalah pengulangan dari jawaban teoman shipahi dengan nama yang sedikit kurang ambigu, dan mengikuti prinsip desain kode pendefinisian sebelum Anda mencoba menyebutnya. (Sementara simpul memungkinkan Anda untuk melakukan sebaliknya, itu bukan praktik yang baik untuk menempatkan kereta di depan kuda.)

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();
        }
    );
}
tidak disinkronkan
sumber
0

Dengan bantuan URL di bawah ini, Anda dapat menyalin atau memindahkan file Anda CURRENT Source to 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 *********/

Abdullah Pariyani
sumber
-6

Anda dapat menggunakan move-filepaket npm:

Pertama instal paket:

$ npm install move-file

Pemakaian:

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
sumber
Jawaban singkat dan Cerdas, Bagus @paridhishah
Abdullah Pariyani
2
Itu adalah panggilan ke fungsi yang belum dibuat sehingga hanya akan membuang kesalahan.
Steve Carey