Dosyaları node.js'de nasıl taşırım?


160

Dosyaları (mv komut kabuğu gibi) node.js üzerinde nasıl taşıyabilirim? Bunun için herhangi bir yöntem var mı yoksa bir dosyayı okuyup yeni bir dosyaya yazıp eski dosyayı kaldırmalı mıyım?

Yanıtlar:


164

Seppo0010 yorumuna göre, bunu yapmak için yeniden adlandırma işlevini kullandım.

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

fs.rename (oldPath, newPath, callback)

Eklendi: v0.0.2

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

Eşzamansız yeniden adlandırma (2). Tamamlama geri aramasına olası bir istisna dışında hiçbir argüman verilmez.


5
@ Seppo0010'un yorumunun nereye gittiğini merak edenler için: cevabımdaydı, sildiğim ve OP'ye yorum olarak gönderdim.
Matt Ball

6
Bu, bölümleri geçiyorsanız veya dosyaların taşınmasını desteklemeyen bir sanal dosya sistemi kullanıyorsanız çalışmayacaktır. Daha iyi kullanmak bu çözümü bir kopyası yedek kullanımıyla
Flavien Volken

48

Bu örnek: Node.js in Action'dan alınmıştır.

Mümkünse yeniden adlandıran veya kopyalamaya geri dönen bir move () işlevi

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
Bir cazibe gibi çalıştı. Teşekkürler! Biraz ekleyebilirsem: oldPath'in bağlantısını kaldırdığında 'taşı' daha iyi bir isim olabilir.
Jokester

Copy () işlevi bu durumda tamamdır, ancak birisi onu bir Promise nesnesinin içine almak isterse, lütfen aşağıdaki "cevabıma" bakın veya yazma akışındaki "close" olayında verilen sözü çözmeyi unutmayın, okuma akışında değil.
Jem

Bu ihtiyaçlarım için işe yarayacak bir şeye benziyor, ancak module.exports = function {} stilini nasıl kullanacağımı bilmiyorum. var fs = require ('fs') 'ye sahip olduğum yerde bu kodu uygulamamın kendisine kopyalıyor muyum; ve sonra fs.rename yerine fs.move (oldFile, newFile, function (err) {....}) çağırın?
Meraklı101

@ Curious101 Bunu filemove.js gibi bir dosyaya koyabilir ve var filemove = require ('filemove') gibi içe aktarabilirsiniz; sonra filemove (...) gibi kullanın;
Teoman shipahi

Teşekkürler @Teomanshipahi. Bu durumda mylibrary.js'ye ekleyebilir ve oradan kullanabilirim. Bunun prototip yöntemleri eklemenin iyi bilinen bir yöntemi olduğunu düşündüm, böylece nesnenin kendisinde kullanılabilir hale gelir.
Meraklı101

44

Nodejs'yi yerel olarak kullanma

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

(NOT: " Bölümler arasında geçiş yapıyorsanız veya dosyaların taşınmasını desteklemeyen bir sanal dosya sistemi kullanıyorsanız bu çalışmayacaktır. [...]" - Flavien Volken 2 Eylül 15:50 ")


31

Önce bir yapmayı deneyecek ve sonra kopyalayıp sonra bağlantıyı kesmeye geri dönecek olan mv düğüm modülünü kullanın fs.rename.


Bir dosyayı taşımak için basit gereksinimler için iyi çalıştı.
arcseldon

1
andrewrk, bu mvdüğüm modülünün yazarı gibi görünüyor . Yüklemek için npm kullanmayı seviyorum; npm install mv --save-dev; işte npm bağlantısı
The Red Pea

4
Bu nasıl bir geliştirici bağımlılığı? Uygulamanın çalışması için mv gerekmez mi?
jgr0

18

util.pump 0.10 düğümünde kullanımdan kaldırılmıştır ve uyarı mesajı oluşturur

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

Dolayısıyla, dosyaları akışları kullanarak kopyalamak için çözüm şudur:

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
Bu, iki farklı bölümdeki bir dosyayı kopyalamanın / taşımanın uygun yoludur. Teşekkür ederim!
slickplaid

11

fs-extraModülü 's ile bunu sağlayan move()yönteme. Ben zaten uyguladım ve bir dosyayı bir dizinden diğerine tamamen taşımak istiyorsanız iyi çalışıyor - yani. dosyayı kaynak dizinden kaldırmak. Çoğu temel durum için çalışmalıdır.

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

Async / await'i kullanabilmeniz için fs-extra dönüşlerin vaat ettiğine inanıyorum
Anthony

9

Yeniden adlandırma işlevini kullanma:

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

nerede

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

dosya adını değiştirmeden tutmak istediğiniz varsayılır.


5
Dosyayı farklı bölümler arasında yeniden adlandırmaya çalışırsanız, ne de bazı sanal dosya sistemlerinde (örneğin docker gibi)
işe yaramayacağına dikkat edin

5

İşte util.pump kullanan bir örnek, >> a dosyasını Node.js'de farklı bir bölüme veya aygıta nasıl taşıyabilirim?

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
Bunu yalnızca dosyaları birimler arasında taşırken yapmanız gerektiğini belirtmek gerekir. Aksi takdirde, kullanabilirsiniz fs.rename()(bir birim içinde bir dosyayı yeniden adlandırmak ve taşımak aynı şeydir).
s4y

4
util.pump kullanımdan kaldırıldı.
andrewrk


Dosyayı yerel makineden sunucuya taşımak mümkün mü?
Hulk1991

Hayır, bunun için başka bir şey kullanmanız gerekir (FTP, HTTP veya başka bir protokol kullanmak gibi).
alessioalex

5

8.0.0'dan büyük Düğüm sürümleri için vaatlerin kullanılması:

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
fs.renameBirimler içeren bir Docker ortamındaysanız yalnızca bir uyarı işe yaramaz.
Atul Yadav

İşleve bir asyncbildirim ekleyin moveThem.
H_I

4

Yukarıdaki cevapta belirtildiği gibi sadece 2 sentim : copy () yöntemi, küçük bir ayarlama olmaksızın dosyaları kopyalamak için olduğu gibi kullanılmamalıdır:

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

Kopyalama işlevi bir Sözle sarılmıştır:

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

Ancak, hedef klasör yoksa dosya sisteminin çökebileceğini unutmayın.


4

Ben ilgili tüm işlevlerini ayırmak istiyorum (yani rename, copy, unlink) elbette, esneklik ve promisify şeyi kazanmak için birbirinden:

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 sadece bir kullanışlılık işlevidir ve işlevleri ayrı ayrı uygulayabiliriz, örneğin daha ince ayrıntılı istisna işlemeye ihtiyacımız olduğunda.


2

Shelljs çok kullanışlı bir çözümdür.

komut: mv ([seçenekler,] kaynak, hedef)

Mevcut seçenekler:

-f: force (varsayılan davranış)

-n: üzerine yazmayı önlemek için

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

Bu, teoman shipahi'nin biraz daha az belirsiz bir adla yanıtının ve siz onu çağırmaya çalışmadan önce kodu tanımlama tasarım prensibini takip eden bir özetidir . (Düğüm aksini yapmanıza izin verirken, arabayı atın önüne koymak iyi bir uygulama değildir.)

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

Aşağıdaki URL'nin yardımıyla, dosyanızı CURRENT Source'u Hedef Kaynağa kopyalayabilir veya taşıyabilirsiniz.

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.