Programing

node.js에서 파일을 복사하는 가장 빠른 방법

lottogame 2020. 2. 18. 22:35
반응형

node.js에서 파일을 복사하는 가장 빠른 방법


내가 작업중 인 프로젝트 (node.js)는 파일 시스템 (복사 / 읽기 / 쓰기 등)으로 많은 작업을 의미합니다. 어떤 방법이 가장 빠른지 알고 싶습니다. 기꺼이 조언을 구하십시오. 감사.


이것은 스트림을 사용하여 한 줄의 코드로 파일을 복사하는 좋은 방법입니다.

var fs = require('fs');

fs.createReadStream('test.log').pipe(fs.createWriteStream('newLog.log'));

노드 v8.5.0에서 copyFile이 추가되었습니다.

const fs = require('fs');

// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
  if (err) throw err;
  console.log('source.txt was copied to destination.txt');
});

동일한 메커니즘이지만 오류 처리가 추가됩니다.

function copyFile(source, target, cb) {
  var cbCalled = false;

  var rd = fs.createReadStream(source);
  rd.on("error", function(err) {
    done(err);
  });
  var wr = fs.createWriteStream(target);
  wr.on("error", function(err) {
    done(err);
  });
  wr.on("close", function(ex) {
    done();
  });
  rd.pipe(wr);

  function done(err) {
    if (!cbCalled) {
      cb(err);
      cbCalled = true;
    }
  }
}

createReadStream/createWriteStream어떤 이유로 든 메소드를 작동 시킬 수 없었지만 fs-extranpm 모듈을 사용하면 즉시 작동했습니다. 그래도 성능 차이는 확실하지 않습니다.

fs-extra

npm install --save fs-extra

var fs = require('fs-extra');

fs.copySync(path.resolve(__dirname,'./init/xxx.json'), 'xxx.json');

Node.js 8.5.0부터 새로운 fs.copyFilefs.copyFileSync 메소드가 있습니다.

사용 예 :

var fs = require('fs');

// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
    if (err) throw err;
    console.log('source.txt was copied to destination.txt');
});

약속 및 오류 관리 기능으로 빠르고 쓰기 쉽고 사용하기 편리합니다.

function copyFile(source, target) {
  var rd = fs.createReadStream(source);
  var wr = fs.createWriteStream(target);
  return new Promise(function(resolve, reject) {
    rd.on('error', reject);
    wr.on('error', reject);
    wr.on('finish', resolve);
    rd.pipe(wr);
  }).catch(function(error) {
    rd.destroy();
    wr.end();
    throw error;
  });
}

async / await 구문과 동일합니다.

async function copyFile(source, target) {
  var rd = fs.createReadStream(source);
  var wr = fs.createWriteStream(target);
  try {
    return await new Promise(function(resolve, reject) {
      rd.on('error', reject);
      wr.on('error', reject);
      wr.on('finish', resolve);
      rd.pipe(wr);
    });
  } catch (error) {
    rd.destroy();
    wr.end();
    throw error;
  }
}

일반적으로 비동기 파일 작업을 피하는 것이 좋습니다. 다음은 짧은 (즉, 오류 처리 없음) 동기화 예입니다.

var fs = require('fs');
fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));

오류 처리기를위한 바로 가기가 포함 된 오류 처리 기능이있는 Mike Schilling 솔루션.

function copyFile(source, target, cb) {
  var cbCalled = false;

  var rd = fs.createReadStream(source);
  rd.on("error", done);

  var wr = fs.createWriteStream(target);
  wr.on("error", done);
  wr.on("close", function(ex) {
    done();
  });
  rd.pipe(wr);

  function done(err) {
    if (!cbCalled) {
      cb(err);
      cbCalled = true;
    }
  }
}

비동기식에 신경 쓰지 않고 기가 바이트 크기의 파일을 복사하지 않고 단일 함수에 대해서만 다른 종속성을 추가하지 않으려는 경우 :

function copySync(src, dest) {
  if (!fs.existsSync(src)) {
    return false;
  }

  var data = fs.readFileSync(src, 'utf-8');
  fs.writeFileSync(dest, data);
}

복사하기 전에 파일의 가시성을 검사하는 benweet의 솔루션 :

function copy(from, to) {
    return new Promise(function (resolve, reject) {
        fs.access(from, fs.F_OK, function (error) {
            if (error) {
                reject(error);
            } else {
                var inputStream = fs.createReadStream(from);
                var outputStream = fs.createWriteStream(to);

                function rejectCleanup(error) {
                    inputStream.destroy();
                    outputStream.end();
                    reject(error);
                }

                inputStream.on('error', rejectCleanup);
                outputStream.on('error', rejectCleanup);

                outputStream.on('finish', resolve);

                inputStream.pipe(outputStream);
            }
        });
    });
}

Mike의 솔루션 이지만 약속이 있습니다.

const FileSystem = require('fs');

exports.copyFile = function copyFile(source, target) {
    return new Promise((resolve,reject) => {
        const rd = FileSystem.createReadStream(source);
        rd.on('error', err => reject(err));
        const wr = FileSystem.createWriteStream(target);
        wr.on('error', err => reject(err));
        wr.on('close', () => resolve());
        rd.pipe(wr);
    });
};

다른 답변의 개선.

풍모:

  • dst 폴더가 없으면 자동으로 생성됩니다. 다른 답변은 오류 만 발생합니다.
  • promise큰 프로젝트에서 사용하기 쉽도록를 반환합니다 .
  • 여러 파일 을 복사 할 수 있으며 모든 파일 이 복사 되면 약속이 수행됩니다.

용법:

var onePromise = copyFilePromise("src.txt", "dst.txt");
var anotherPromise = copyMultiFilePromise(new Array(new Array("src1.txt", "dst1.txt"), new Array("src2.txt", "dst2.txt")));

암호:

function copyFile(source, target, cb) {
    console.log("CopyFile", source, target);

    var ensureDirectoryExistence = function (filePath) {
        var dirname = path.dirname(filePath);
        if (fs.existsSync(dirname)) {
            return true;
        }
        ensureDirectoryExistence(dirname);
        fs.mkdirSync(dirname);
    }
    ensureDirectoryExistence(target);

    var cbCalled = false;
    var rd = fs.createReadStream(source);
    rd.on("error", function (err) {
        done(err);
    });
    var wr = fs.createWriteStream(target);
    wr.on("error", function (err) {
        done(err);
    });
    wr.on("close", function (ex) {
        done();
    });
    rd.pipe(wr);
    function done(err) {
        if (!cbCalled) {
            cb(err);
            cbCalled = true;
        }
    }
}

function copyFilePromise(source, target) {
    return new Promise(function (accept, reject) {
        copyFile(source, target, function (data) {
            if (data === undefined) {
                accept();
            } else {
                reject(data);
            }
        });
    });
}

function copyMultiFilePromise(srcTgtPairArr) {
    var copyFilePromiseArr = new Array();
    srcTgtPairArr.forEach(function (srcTgtPair) {
        copyFilePromiseArr.push(copyFilePromise(srcTgtPair[0], srcTgtPair[1]));
    });
    return Promise.all(copyFilePromiseArr);
}

내장 복사 기능으로 nodejs를 사용하지 않는 이유는 무엇입니까?

비동기 및 동기화 버전을 모두 제공합니다.

const fs = require('fs');

// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
  if (err) throw err;
  console.log('source.txt was copied to destination.txt');
});

https://nodejs.org/api/fs.html#fs_fs_copyfilesync_src_dest_flags


빠른 복사를 위해서는 fs.constants.COPYFILE_FICLONE플래그를 사용해야합니다 . (이를 지원하는 파일 시스템의 경우) 실제로 파일의 내용을 복사하지 못하게합니다. 새 파일 항목 만 작성되지만 소스 파일 Copy-on-Write "복제본"을 가리 킵니다 .

아무것도하지 않거나 덜하는 것은 무언가를하는 가장 빠른 방법입니다.)

https://nodejs.org/api/fs.html#fs_fs_copyfile_src_dest_flags_callback

let fs = require("fs");

fs.copyFile(
  "source.txt",
  "destination.txt",
  fs.constants.COPYFILE_FICLONE,
  (err) => {
    if (err) {
      // TODO: handle error
      console.log("error");
    }
    console.log("success");
  }
);

대신 약속을 사용하십시오.

let fs = require("fs");
let util = require("util");
let copyFile = util.promisify(fs.copyFile);


copyFile(
  "source.txt",
  "destination.txt",
  fs.constants.COPYFILE_FICLONE
)
  .catch(() => console.log("error"))
  .then(() => console.log("success"));

소스 파일의 존재를 확인하지 않는 위의 모든 솔루션은 위험합니다 ... 예 :

fs.stat(source, function(err,stat) { if (err) { reject(err) }

그렇지 않으면 소스와 대상이 실수로 대체 된 경우 시나리오에서 위험이 있으며 오류를 알리지 않고 데이터가 영구적으로 손실됩니다.


   const fs = require("fs");
   fs.copyFileSync("filepath1", "filepath2"); //fs.copyFileSync("file1.txt", "file2.txt");

이것은 개인적으로 파일을 복사하고 node.js를 사용하여 다른 파일을 대체하는 데 사용합니다 :)

참고 URL : https://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js

반응형