ฉันจะย้ายไฟล์ใน node.js ได้อย่างไร


151

ฉันจะย้ายไฟล์ (เช่น mv command shell) บน node.js ได้อย่างไร มีวิธีการใดที่ฉันควรอ่านไฟล์เขียนไปยังไฟล์ใหม่และลบไฟล์เก่า

คำตอบ:


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>

เปลี่ยนชื่อแบบอะซิงโครนัส (2) ไม่มีข้อโต้แย้งอื่นใดนอกจากข้อยกเว้นที่เป็นไปได้จะถูกกำหนดให้กับการเรียกกลับที่สมบูรณ์


5
สำหรับผู้ที่สงสัยว่าความคิดเห็นของ @ seppo0010 ไปที่: มันเป็นคำตอบของฉันซึ่งฉันลบและโพสต์เป็นความคิดเห็นใน OP
Matt Ball

6
สิ่งนี้จะไม่ทำงานหากคุณข้ามพาร์ทิชันหรือใช้ระบบไฟล์เสมือนที่ไม่รองรับการย้ายไฟล์ คุณควรใช้โซลูชันนี้กับสำเนาสำรอง
Flavien Volken

คำตอบที่ 3 โดย "Hani" มีรหัสตัวอย่าง!
นาธาน

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
Jokester

ฟังก์ชั่น copy () นั้นใช้ได้ในกรณีนี้ แต่ถ้ามีคนต้องการห่อไว้ในวัตถุสัญญาโปรดดูคำตอบของฉันด้านล่างหรือจำไว้เพื่อแก้ไขสัญญาในเหตุการณ์ "ปิด" ในสตรีมการเขียน ไม่ได้อยู่ในสตรีมการอ่าน
Jem

ดูเหมือนว่าจะมีบางสิ่งที่เหมาะกับความต้องการของฉัน แต่ฉันไม่รู้วิธีใช้สไตล์ module.exports = function {} ฉันจะคัดลอกรหัสนี้ไปยังแอปของฉันเองที่ฉันมี var fs = require ('fs') อยู่แล้วหรือไม่ จากนั้นเรียก fs.move (oldFile, newFile, function (err) {.... }) แทน fs.rename?
Curious101

@ Curious101 คุณสามารถใส่มันลงในไฟล์เช่น filemove.js และนำเข้ามันเช่น var filemove = require ('filemove'); จากนั้นใช้มันเหมือน filemove (... );
Teoman shipahi

ขอบคุณ @Tomomhiphipahi ในกรณีนี้ฉันสามารถเพิ่มไปยัง 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 2 ก.ย. 15 'ในเวลา 12:50 ")


30

ใช้โมดูลโหนดmvซึ่งจะพยายามทำfs.renameก่อนแล้วเลือกสำรองเพื่อคัดลอกแล้วยกเลิกการเชื่อมโยง


ทำงานได้ดีสำหรับความต้องการง่าย ๆ ในการย้ายไฟล์
arcseldon

1
andrewrk ดูเหมือนจะเป็นผู้เขียนของmvโมดูลโหนดนี้ ฉันชอบใช้ npm เพื่อติดตั้ง; npm install mv --save-dev; นี่คือลิงค์ npm
Red Pea

3
นี่คือการพึ่งพาของ dev อย่างไร แอปพลิเคชันไม่ต้องการ 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
นี่เป็นวิธีที่เหมาะสมในการคัดลอก / ย้ายไฟล์ที่อยู่ในสองพาร์ติชั่นที่ต่างกัน ขอบคุณ!
slickplaid

9

ใช้ฟังก์ชั่นการเปลี่ยนชื่อ:

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

ที่ไหน

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

สมมติว่าคุณต้องการให้ชื่อไฟล์ไม่เปลี่ยนแปลง


4
ระวังสิ่งนี้จะไม่ทำงานหากคุณพยายามเปลี่ยนชื่อไฟล์ระหว่างพาร์ติชั่นต่าง ๆ ทั้งในระบบไฟล์เสมือน (เช่น docker เป็นต้น)
docker

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 จาก >> ฉันจะย้ายไฟล์ไปยังพาร์ติชั่นหรืออุปกรณ์อื่นใน 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

ไม่, คุณต้องใช้อย่างอื่นสำหรับสิ่งนั้น (เช่นการใช้ FTP, HTTP หรือโปรโตคอลอื่น)
alessioalex

4

การใช้สัญญาสำหรับโหนดเวอร์ชันที่มากกว่า 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
เพียงแค่คำเตือนfs.renameไม่สามารถใช้งานได้หากคุณอยู่ในสภาพแวดล้อมของ Docker ที่มีโวลุ่ม
Atul Yadav

เพิ่มการasyncประกาศไปยังmoveThemฟังก์ชัน
H_I

3

เพียง 2 เซ็นต์ของฉันตามที่ระบุไว้ในคำตอบข้างต้น : ไม่ควรใช้วิธีคัดลอก () ตาม - สำหรับการคัดลอกไฟล์โดยไม่มีการปรับแต่งเล็กน้อย:

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

ฉันจะแยกฟังก์ชั่นที่เกี่ยวข้องทั้งหมด (เช่นrename, copy, unlink) จากแต่ละอื่น ๆ ที่จะได้รับความยืดหยุ่นและทุกอย่าง 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 ([ตัวเลือก] แหล่งที่มาปลายทาง)

ตัวเลือกที่มี:

-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 ด้านล่างคุณสามารถคัดลอกหรือย้ายไฟล์ปัจจุบันของคุณไปยังแหล่งปลายทาง

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-fileแพ็คเกจ npm:

ก่อนติดตั้งแพคเกจ:

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

คำตอบสั้น ๆ และสมาร์ท @paridhishah ดี
Abdullah Pariyani

2
นั่นเป็นการเรียกฟังก์ชั่นที่ยังไม่ได้สร้างขึ้นดังนั้นจะเกิดข้อผิดพลาดขึ้นเท่านั้น
Steve Carey
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.