Làm cách nào để di chuyển tệp trong tệp node.js?


151

Làm cách nào tôi có thể di chuyển các tệp (như mv lệnh shell) trên node.js? Có phương pháp nào cho việc đó hay tôi nên đọc một tệp, ghi vào một tệp mới và xóa tệp cũ hơn?

Câu trả lời:


157

Theo nhận xét của seppo0010, tôi đã sử dụng chức năng đổi tên để làm điều đó.

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

fs.rename (oldPath, newPath, gọi lại)

Đã thêm vào: v0.0.2

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

Đổi tên không đồng bộ (2). Không có đối số nào ngoài một ngoại lệ có thể được đưa ra cho cuộc gọi lại hoàn thành.


5
Đối với những người thắc mắc bình luận của @ seppo0010 đã đi đâu: đó là câu trả lời của tôi, tôi đã xóa và đăng dưới dạng nhận xét về OP.
Matt Ball

6
Điều này sẽ không hoạt động nếu bạn đang vượt qua các phân vùng hoặc sử dụng một hệ thống tệp ảo không hỗ trợ các tệp di chuyển. Bạn nên sử dụng giải pháp này với một bản sao lưu dự phòng
Flavien Volken

Câu trả lời thứ 3 của "Hani" có mã ví dụ!
Nathan

47

Ví dụ này được lấy từ: Node.js in Action

Hàm move () đổi tên, nếu có thể hoặc quay lại sao chép

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
Làm việc như người ở. Cảm ơn! Nếu tôi có thể thêm một chút: 'di chuyển' có thể là một tên tốt hơn khi nó hủy liên kết oldPath.
Jokester

Hàm copy () vẫn ổn trong trường hợp này, nhưng nếu ai đó có nghĩa là bọc nó bên trong một đối tượng Promise, vui lòng xem "câu trả lời" của tôi bên dưới hoặc ghi nhớ để giải quyết lời hứa khi sự kiện "đóng" trên luồng ghi, không phải trên luồng đọc.
Jem

Điều này trông giống như một cái gì đó sẽ hoạt động cho nhu cầu của tôi, tuy nhiên tôi không biết cách sử dụng kiểu module.exports = function {}. Tôi có sao chép mã này vào chính ứng dụng của mình không, nơi tôi đã có var fs = quiries ('fs'); và sau đó gọi fs.move (oldFile, newFile, function (err) {....}) thay vì fs.rename?
Tò mò 101

@ Curious101 Bạn có thể đặt tệp này vào một tệp như filemove.js và nhập nó như var filemove = quiries ('filemove'); sau đó sử dụng nó như filemove (...);
Teoman shipahi

Cảm ơn @Teomanshipahi. Trong trường hợp đó tôi có thể thêm vào myl Library.js và sử dụng nó từ đó. Tôi nghĩ rằng đây là một số phương pháp nổi tiếng để thêm các phương thức nguyên mẫu để nó trở nên có sẵn trong chính đối tượng.
Curious101

35

Sử dụng nodejs nguyên bản

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

(LƯU Ý: "Điều này sẽ không hoạt động nếu bạn đang vượt qua các phân vùng hoặc sử dụng hệ thống tệp ảo không hỗ trợ các tệp di chuyển. [...]" - Flavien Volken ngày 2 tháng 9, 15 lúc 12:50 ")


30

Sử dụng mô-đun nút mv trước tiên sẽ cố gắng thực hiện fs.renamevà sau đó sao lưu để sao chép và sau đó hủy liên kết.


Làm việc tốt cho các yêu cầu đơn giản để di chuyển một tập tin.
arcseldon

1
andrewrk dường như là tác giả của mvmô-đun nút này . Tôi thích sử dụng npm để cài đặt; npm install mv --save-dev; đây là liên kết npm
The Red Pea

3
Làm thế nào đây là một phụ thuộc dev? Không phải ứng dụng yêu cầu mv để hoạt động sao?
jgr0

17

util.pump không được dùng trong nút 0.10 và tạo thông điệp cảnh báo

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

Vì vậy, giải pháp để sao chép tệp bằng luồng là:

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
Đây là cách thích hợp để sao chép / di chuyển một tệp nằm trên hai phân vùng khác nhau. Cảm ơn bạn!
slickplaid

9

Sử dụng chức năng đổi tên:

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

Ở đâu

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

giả định rằng bạn muốn giữ tên tệp không thay đổi.


4
Hãy cẩn thận, điều này sẽ không hoạt động nếu bạn cố đổi tên tệp giữa các phân vùng khác nhau, không phải trên một số hệ thống tệp ảo (chẳng hạn như
docker

8

Các fs-extramô-đun cho phép bạn làm điều này với nó của move()phương pháp. Tôi đã thực hiện nó và nó hoạt động tốt nếu bạn muốn di chuyển hoàn toàn một tập tin từ thư mục này sang thư mục khác - tức là. loại bỏ các tập tin từ thư mục nguồn. Nên làm việc cho hầu hết các trường hợp cơ bản.

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

Dưới đây là một ví dụ sử dụng produc.pump, từ >> Làm cách nào để di chuyển tệp a sang một phân vùng hoặc thiết bị khác trong 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
Điều đáng chú ý là bạn chỉ phải làm điều này khi di chuyển tệp qua các ổ đĩa. Mặt khác, bạn chỉ có thể sử dụng fs.rename()(trong một ổ đĩa đổi tên một tệp và di chuyển nó là điều tương tự).
s4y

4
produc.pump không được dùng nữa.
andrewrk


Có thể di chuyển tập tin từ máy cục bộ sang máy chủ?
Hulk1991

Không, bạn cần sử dụng một cái gì đó khác cho điều đó (như sử dụng FTP, HTTP hoặc giao thức khác).
alessioalex

4

Sử dụng lời hứa cho các phiên bản Node lớn hơn 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
Chỉ cần một lời cảnh báo fs.renamesẽ không hoạt động nếu bạn đang ở trong môi trường Docker có âm lượng.
Atul Yadav

Thêm một asynckhai báo cho moveThemhàm.
H_I

3

Chỉ 2 xu của tôi như đã nêu trong câu trả lời ở trên : Phương thức copy () không nên được sử dụng như là để sao chép các tệp mà không cần điều chỉnh một chút:

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

Hàm sao chép được gói trong 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);
  })

Tuy nhiên, hãy nhớ rằng hệ thống tập tin có thể bị sập nếu thư mục đích không tồn tại.


3

Tôi sẽ tách tất cả các chức năng có liên quan (ví dụ rename, copy, unlink) lẫn nhau để đạt được sự linh hoạt và promisify tất cả mọi thứ, tất nhiên:

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 chỉ là một chức năng tiện lợi và chúng ta có thể áp dụng các chức năng một cách riêng biệt, ví dụ như khi chúng ta cần xử lý ngoại lệ chi tiết hơn.


2

Vỏ ốc là một giải pháp rất tiện dụng.

lệnh: mv ([tùy chọn,] nguồn, đích)

Tùy chọn có sẵn:

-f: lực lượng (hành vi mặc định)

-n: để ngăn chặn ghi đè

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

đây là một bản tóm tắt của câu trả lời của teoman shipahi với một cái tên ít mơ hồ hơn và tuân theo nguyên tắc thiết kế xác định mã trước khi bạn cố gắng gọi nó. (Trong khi nút cho phép bạn làm khác, thì việc đặt xe trước ngựa không phải là điều tốt.)

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

Với sự trợ giúp của URL bên dưới, bạn có thể sao chép hoặc di chuyển tệp HIỆN TẠI Nguồn sang Nguồn đích

https://ciftsweb.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

Bạn có thể dùng move-file gói npm:

Đầu tiên cài đặt gói:

$ npm install move-file

Sử dụng:

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

Câu trả lời ngắn gọn và thông minh, Tốt @paridhishah
Abdullah Pariyani

2
Đó là một cuộc gọi đến một chức năng chưa được tạo nên sẽ chỉ gây ra lỗi.
Steve Carey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.