node.jsでファイルを移動するにはどうすればよいですか?


151

node.jsでファイル(mvコマンドシェルなど)を移動するにはどうすればよいですか?そのための方法はありますか、またはファイルを読み取り、新しいファイルに書き込み、古いファイルを削除する必要がありますか?

回答:


157

seppo0010のコメントによると、私はそのために名前変更機能を使用しました。

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

fs.rename(oldPath、newPath、callback)

追加:v0.0.2

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

非同期のrename(2)。起こりうる例外以外の引数は、完了コールバックに渡されません。


5
@ seppo0010のコメントがどこに行ったのか疑問に思っている人のために:それは私の答えにありました、私はそれを削除してOPへのコメントとして投稿しました。
Matt Ball

6
パーティションをまたいだり、ファイルの移動をサポートしていない仮想ファイルシステムを使用している場合、これは機能しません。コピーフォールバックでこのソリューションをより適切に使用する
Flavien Volken

「ハニ」の3番目の回答にはサンプルコードがあります。
ネイサン

47

この例は、Node.jsの実際の例です。

可能であれば名前を変更するか、コピーにフォールバックするmove()関数

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
魅力のように働いた。ありがとう!私が少し追加する場合:oldPathのリンクを解除するときは、「move」の方が適切な名前かもしれません。
ジョークスター2017

この場合copy()関数は問題ありませんが、誰かがそれをPromiseオブジェクト内にラップすることを意味する場合は、以下の「答え」を参照するか、書き込みストリームの「閉じる」イベントでの約束を解決するように心がけてください。読み取りストリームにはありません。
Jem

これは私のニーズに合うもののように見えますが、module.exports = function {}スタイルの使用方法がわかりません。var fs = require( 'fs');が既にあるアプリ自体にこのコードをコピーしますか?次に、fs.renameの代わりにfs.move(oldFile、newFile、function(err){....})を呼び出しますか?
Curious101

@ Curious101これをfilemove.jsのようなファイルに入れて、var filemove = require( 'filemove');のようにインポートできます。次に、filemove(...)のように使用します。
Teoman Shipahi

@Teomanshipahiに感謝します。その場合、mylibrary.jsに追加して、そこから使用できます。これはプロトタイプメソッドを追加するよく知られた方法であり、オブジェクト自体で使用できるようになると思いました。
Curious101

35

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

(注:「パーティションをまたいでいるか、ファイルの移動をサポートしていない仮想ファイルシステムを使用している場合、これは機能しません。[...]」 – Flavien Volken Sep 2 '15 at 12:50 ")


30

mvノードモジュールを使用します。このモジュールは、最初に試行しfs.rename、次にコピーにフォールバックしてからリンク解除します。


ファイルを移動するという単純な要件でうまく機能しました。
arcseldon

1
andrewrkがこのmvノードモジュールの作成者のようです。インストールにnpmを使用するのが好きです。npm install mv --save-dev; ここにnpmリンクがあります
Red Pea

3
これはどのように開発依存関係ですか?アプリは機能するためにmvを必要としませんか?
jgr0

17

util.pump ノード0.10では非推奨であり、警告メッセージを生成します

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

したがって、ストリームを使用してファイルをコピーするためのソリューションは次のとおりです。

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
これは、2つの異なるパーティションにあるファイルをコピー/移動する適切な方法です。ありがとうございました!
slickplaid 2014

9

名前変更機能の使用:

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

どこ

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

ファイル名を変更しないと仮定します。


4
異なるパーティション間でファイルの名前を変更しようとしても、一部の仮想ファイルシステム(dockerなど)では機能しないことに注意してください
Flavien Volken

8

fs-extraモジュールは、あなたがそれのでこれを行うことを可能にするmove()方法。私はすでにそれを実装しており、あるディレクトリから別のディレクトリにファイルを完全に移動したい場合はうまくいきます。ソースディレクトリからファイルを削除します。ほとんどの基本的なケースで機能するはずです。

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

>>からのutil.pumpの使用例を次に示します。 >> ファイルaを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
ボリューム間でファイルを移動する場合にのみ、これを行う必要があることに注意してください。それ以外の場合は、そのまま使用できますfs.rename()(ボリューム内でファイルの名前を変更して移動することは同じです)。
s4y

4
util.pumpは非推奨です。
andrewrk


ローカルマシンからサーバーにファイルを移動できますか?
Hulk1991 2013

いいえ、そのために別のものを使用する必要があります(FTP、HTTP、または別のプロトコルを使用するなど)。
alessioalex 2013

4

8.0.0以降のNodeバージョンのpromiseの使用:

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.renameボリュームのあるDocker環境では、注意事項は機能しません。
Atul Yadav

関数にasync宣言を追加しmoveThemます。
H_I

3

上記答えで述べたように、ちょうど私の2セント:copy()メソッドは、わずかな調整なしでファイルをコピーするために、そのまま使用しないでください。

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

Promiseにラップされたコピー機能:

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

ただし、ターゲットフォルダーが存在しない場合、ファイルシステムがクラッシュする可能性があることに注意してください。


3

私が関係するすべての機能を分離う(すなわちrenamecopyunlink)もちろん、柔軟性とpromisifyすべてを得るために、互いから:

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 は単なる便利な関数であり、たとえば、よりきめの細かい例外処理が必要な場合に、関数を個別に適用できます。


2

Shelljsは非常に便利なソリューションです。

コマンド:mv([options、] source、destination)

利用可能なオプション:

-f:force(デフォルトの動作)

-n:上書きを防止する

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

これは、teoman shipahiの回答を少しあいまいな名前で書き直したものであり、コードを呼び出す前にコードを定義するという設計原則に従っています。(ノードでは別の方法を使用できますが、カートを馬の前に置くことはお勧めできません。)

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

以下のURLの助けを借りて、ファイルをコピーまたは移動することができます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 *********/



-6

move-filenpmパッケージを使用できます。

最初にパッケージをインストールします。

$ npm install move-file

使用法:

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

短くてスマートな答え、Good @paridhishah
Abdullah Pariyani 19/07/12

2
それはまだ作成されていない関数の呼び出しなので、単にエラーをスローします。
Steve Carey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.