คัดลอกโฟลเดอร์ซ้ำใน node.js


154

มีวิธีที่ง่ายกว่าในการคัดลอกโฟลเดอร์และเนื้อหาทั้งหมดโดยไม่ต้องทำตามลำดับด้วยตนเอง fs.readir , fs.readfile, fs.writefileซ้ำ?

เพียงแค่สงสัยว่าฉันขาดฟังก์ชั่นใดที่จะใช้งานได้ดีเช่นนี้

fs.copy("/path/to/source/folder","/path/to/destination/folder");

3
มีวิธีการทำเช่นนี้โดยไม่มีโมดูลใด ๆ ? อาจจะเป็นฟังก์ชั่นซ้ำ / รหัส snip-it?
Sukima

@Sukima - ดูคำตอบของฉันที่นี่
jmort253

คำตอบ:


121

คุณสามารถใช้โมดูลncp ฉันคิดว่านี่คือสิ่งที่คุณต้องการ


2
ที่สมบูรณ์แบบ! npm install ncpและทำงานในเวลาน้อยกว่า 30 วินาที ขอบคุณ
Aebsubis

1
ประแจดีกว่าสำหรับฉันเพราะมันรองรับตัวเลือกเพิ่มเติม ด้วย NCP คุณไม่สามารถแก้ไข symlink ได้
Slava Fomin II

3
เป็นโบนัสที่น่าอัศจรรย์เราสามารถใช้ ncp ใน cross platform npm run script
Ciantic

ฉันได้รับกรณีง่าย ๆ ที่ ncp ไม่ได้อยู่ในการติดต่อกลับของฉันที่ fs-extra ทำได้อย่างถูกต้อง
bumpmann

40
โปรดทราบว่า ncp ดูเหมือนจะไม่มีการควบคุม fs-extraน่าจะเป็นตัวเลือกที่ดีที่สุดแทน
chris

74

นี่เป็นวิธีการของฉันในการแก้ปัญหานี้โดยไม่ต้องมีโมดูลเพิ่มเติม เพียงแค่ใช้ในตัวfsและpathโมดูล

หมายเหตุ:นี่ใช้ฟังก์ชันอ่าน / เขียนของ fs ดังนั้นจึงไม่คัดลอกข้อมูลเมตาใด ๆ (เวลาที่สร้างเป็นต้น) ณ โหนด 8.5 มีcopyFileSyncฟังก์ชั่นที่ใช้งานซึ่งเรียกใช้ฟังก์ชั่นการคัดลอก OS ดังนั้นจึงคัดลอกข้อมูลเมตา ฉันยังไม่ได้ทดสอบพวกเขา แต่มันควรจะทำงานเพื่อแทนที่พวกเขา (ดูhttps://nodejs.org/api/fs.html#fs_fs_copyfilesync_src_dest_flags )

var fs = require('fs');
var path = require('path');

function copyFileSync( source, target ) {

    var targetFile = target;

    //if target is a directory a new file with the same name will be created
    if ( fs.existsSync( target ) ) {
        if ( fs.lstatSync( target ).isDirectory() ) {
            targetFile = path.join( target, path.basename( source ) );
        }
    }

    fs.writeFileSync(targetFile, fs.readFileSync(source));
}

function copyFolderRecursiveSync( source, target ) {
    var files = [];

    //check if folder needs to be created or integrated
    var targetFolder = path.join( target, path.basename( source ) );
    if ( !fs.existsSync( targetFolder ) ) {
        fs.mkdirSync( targetFolder );
    }

    //copy
    if ( fs.lstatSync( source ).isDirectory() ) {
        files = fs.readdirSync( source );
        files.forEach( function ( file ) {
            var curSource = path.join( source, file );
            if ( fs.lstatSync( curSource ).isDirectory() ) {
                copyFolderRecursiveSync( curSource, targetFolder );
            } else {
                copyFileSync( curSource, targetFolder );
            }
        } );
    }
}

จะไม่คัดลอกโฟลเดอร์หากมีที่ว่างในชื่อ
31415926

สำหรับฉันมันจะคัดลอกโฟลเดอร์ที่มีช่องว่างในชื่อของพวกเขา อาจเกิดจากข้อผิดพลาดที่แก้ไขโดย @victor ขณะที่ฉันใช้งานฟังก์ชั่นนี้ค่อนข้างสม่ำเสมอ (ในสถานะปัจจุบันในขณะที่ฉันลืมที่จะอัพเดทผู้ชนะการแก้ไขที่เหมือนกัน) ฉันมั่นใจว่ามันใช้งานได้ทั่วไป
Simon Zyx

1
ความต้องการ: javascript var fs = require('fs'); var path = require('path');
Tyler

2
สิ่งนี้ไม่ได้คัดลอกไฟล์ มันอ่านแล้วเขียนพวกเขา นั่นไม่ใช่การคัดลอก การคัดลอกประกอบด้วยวันที่สร้างรวมถึงสตรีมข้อมูลเมตาอื่น ๆ ที่ทั้ง Windows และ MacOS สนับสนุนและไม่ได้คัดลอกด้วยรหัสนี้ ณ โหนด 8.5 คุณควรโทรfs.copyหรือfs.copySyncตามที่จริงเรียกฟังก์ชันการคัดลอกระดับ OS ใน MacOS และ Windows และคัดลอกไฟล์
gman

1
ขอโทษมันfs.copyFileและถ้าขุดของคุณผ่านโหนดต้นทางที่คุณจะเห็นบน Mac และ Windows ที่พวกเขาเรียกฟังก์ชั่นระบบปฏิบัติการที่เฉพาะเจาะจงในการคัดลอกไฟล์
G-Man

52

มีบางโมดูลที่รองรับการคัดลอกโฟลเดอร์พร้อมเนื้อหา ที่นิยมกันมากที่สุดก็คือประแจ

// Deep-copy an existing directory
wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');

ทางเลือกจะเป็นnode-fs-extra

fs.copy('/tmp/mydir', '/tmp/mynewdir', function (err) {
  if (err) {
    console.error(err);
  } else {
    console.log("success!");
  }
}); //copies directory, even if it has subdirectories or files

3
ประแจล้มเหลวหากไดเรกทอรีที่จะคัดลอกมีลิงค์สัญลักษณ์
DoubleMalt

2
มันยังล้มเหลวบน Windows หากมีไดเรกทอรีอยู่แล้วncpทำงานได้ทันทีจากกระเป๋า
เบลนด์

6
node-fs-extra ใช้งานได้สำหรับฉัน มันสืบทอด fs ดั้งเดิมและฉันชอบมันเป็นวิธีการจัดการกระบวนการ รหัสน้อยกว่าที่จะอัปเดตในแอป
dvdmn

15
โปรดทราบว่าwrenchเลิกใช้แล้วและควรจะถูกแทนที่ด้วยnode-fs-extra( github.com/jprichardson/node-fs-extra )
Ambidex

1
ประแจไม่ได้คัดลอกไฟล์จริงๆ มันอ่านแล้วเขียนพวกเขาแล้วคัดลอกวันที่ของพวกเขา นั่นไม่ใช่การคัดลอก การคัดลอกรวมถึงสตรีมข้อมูลเมตาอื่น ๆ ที่รองรับ Windows และ MacOS และไม่ได้คัดลอกด้วยประแจ
gman

38

นี่คือฟังก์ชันที่คัดลอกไดเรกทอรีซ้ำและเนื้อหาไปยังไดเรกทอรีอื่น:

const fs = require("fs")
const path = require("path")

/**
 * Look ma, it's cp -R.
 * @param {string} src The path to the thing to copy.
 * @param {string} dest The path to the new copy.
 */
var copyRecursiveSync = function(src, dest) {
  var exists = fs.existsSync(src);
  var stats = exists && fs.statSync(src);
  var isDirectory = exists && stats.isDirectory();
  if (isDirectory) {
    fs.mkdirSync(dest);
    fs.readdirSync(src).forEach(function(childItemName) {
      copyRecursiveSync(path.join(src, childItemName),
                        path.join(dest, childItemName));
    });
  } else {
    fs.copyFileSync(src, dest);
  }
};

3
แม้ว่าคุณจะใส่ฟังก์ชั่นการคัดลอกจริงที่คุณไม่ควรทำตามการเชื่อมโยงสัญลักษณ์ (ใช้fs.lstatSyncแทนfs.statSync)
ไซมอน ZYX

3
สิ่งที่อาจทำให้เกิดความสับสนนี้คือ fs.unlink ลบไฟล์ แต่ fs.link ไม่ได้คัดลอก แต่เชื่อมโยง
Simon Zyx

3
@SimonSeyock: ถูกต้อง .. ไอที linkingไม่ได้คัดลอก .. ปัญหาคือเมื่อคุณแก้ไขเนื้อหาของไฟล์ที่ลิงค์ไฟล์ต้นฉบับจะเปลี่ยนไปด้วย
Abdennour TOUMI


22

สำหรับ linux / unix OS คุณสามารถใช้ไวยากรณ์ของเชลล์ได้

const shell = require('child_process').execSync ; 

const src= `/path/src`;
const dist= `/path/dist`;

shell(`mkdir -p ${dist}`);
shell(`cp -r ${src}/* ${dist}`);

แค่นั้นแหละ!


1
ยินดีต้อนรับ Abd
Abdennour TOUMI

1
นี่คือทางออกที่ง่ายที่สุด ไม่จำเป็นต้องคิดค้นเครื่องมือ UNIX ขึ้นมาใหม่!
Michael Franzl

11
ตั้งแต่ nodejs วิ่งบน OSX / Linux / หน้าต่างนี้เท่านั้นคือคำตอบสำหรับ 2 ไม่ได้ทั้งหมด 3
mjwrazor

2
@AbdennourTOUMI ถ้าคุณใช้ Windows Server
mjwrazor

3
นั่นเป็นเหตุผลที่ฉันเริ่มคำตอบโดย "สำหรับ Linux / Unix OS คุณสามารถใช้เชลล์ไวยากรณ์ .. " 👍🏼
Abdennour TOUMI

19

โมดูล fs-Extra ใช้งานได้อย่างมีเสน่ห์

ติดตั้ง fs-Extra

$ npm install fs-extra

ต่อไปนี้เป็นโปรแกรมที่จะคัดลอกไดเรกทอรีต้นทางไปยังไดเรกทอรีปลายทาง

// include fs-extra package
var fs = require("fs-extra");

var source = 'folderA'
var destination = 'folderB'

// copy source folder to destination
fs.copy(source, destination, function (err) {
    if (err){
        console.log('An error occured while copying the folder.')
        return console.error(err)
    }
    console.log('Copy completed!')
});

อ้างอิง

fs-extra: https://www.npmjs.com/package/fs-extra

ตัวอย่าง: NodeJS บทช่วยสอน - Node.js คัดลอกโฟลเดอร์


กระบวนการนี้จะแทนที่ไดเรกทอรีหรือรวมกับมันได้หรือไม่
SM Shahinul Islam

14

นี่คือวิธีที่ฉันจะทำเอง:

function copyFolderSync(from, to) {
    fs.mkdirSync(to);
    fs.readdirSync(from).forEach(element => {
        if (fs.lstatSync(path.join(from, element)).isFile()) {
            fs.copyFileSync(path.join(from, element), path.join(to, element));
        } else {
            copyFolderSync(path.join(from, element), path.join(to, element));
        }
    });
}

ทำงานกับโฟลเดอร์และไฟล์


3
วิธีการแก้ปัญหานี้สั้นและตรงไปตรงมา นี่จะเป็นวิธีที่ฉันทำอย่างนั้น +1 จากฉัน คุณควรปรับปรุงคำตอบด้วยความคิดเห็นในรหัสของคุณและอธิบายว่าทำไมโซลูชันนี้จึงเป็นที่ต้องการเหนือผู้อื่นและอาจมีข้อเสียอะไรบ้าง - ปรับปรุงโมดูลที่ต้องการ ("path", "fs")
Andrew

ตรวจสอบว่าโฟลเดอร์มีอยู่ที่ด้านบน ... จะช่วยชีวิต ;-) ถ้า (! fs.existsSync (ไป)) fs.mkdirSync (ไป);
โทเบียส

9

ฉันสร้างตัวอย่างการทำงานขนาดเล็กที่คัดลอกโฟลเดอร์ต้นทางไปยังโฟลเดอร์ปลายทางอื่นในไม่กี่ขั้นตอน (ตาม @ shift66 คำตอบโดยใช้ ncp):

ขั้นตอนที่ 1 - ติดตั้งโมดูล ncp:

npm install ncp --save

ขั้นตอนที่ 2 - สร้าง copy.js (แก้ไข srcPath และ destPath vars เป็นสิ่งที่คุณต้องการ):

var path = require('path');
var ncp = require('ncp').ncp;

ncp.limit = 16;

var srcPath = path.dirname(require.main.filename); //current folder
var destPath = '/path/to/destination/folder'; //Any destination folder

console.log('Copying files...');
ncp(srcPath, destPath, function (err) {
  if (err) {
    return console.error(err);
  }
  console.log('Copying files complete.');
});

ขั้นตอนที่ 3 - เรียกใช้

node copy.js

7

นี่เป็นเรื่องง่ายสำหรับโหนด 10

const FSP = require('fs').promises;

async function copyDir(src,dest) {
    const entries = await FSP.readdir(src,{withFileTypes:true});
    await FSP.mkdir(dest);
    for(let entry of entries) {
        const srcPath = Path.join(src,entry.name);
        const destPath = Path.join(dest,entry.name);
        if(entry.isDirectory()) {
            await copyDir(srcPath,destPath);
        } else {
            await FSP.copyFile(srcPath,destPath);
        }
    }
}

สมมติฐานนี้destไม่มีอยู่


3
เราสามารถทำให้มันใช้งานได้ใน Node 8.x โดยใช้require('util').promisifyกับfs.mkdirและfs.copyFileแทนที่จะrequire('fs').promisesเป็นซึ่งยังคงเป็นรุ่นทดลองที่ v11.1
SầnTrần-Nguyễn

@sntran 8.x มีwithFileTypesตัวเลือกหรือไม่? เพราะนั่นช่วยให้คุณไม่ต้องstatโทร
mpen

น่าเสียดายที่ 8.x ไม่มีwithFileTypesตัวเลือก
-Nguyễn

@ SơnTrần-Nguyễn 8.x มาถึงจุดสิ้นสุดของชีวิตเมื่อวันที่ 31 ธันวาคม 2019 - อาจถึงเวลาที่จะอัพเกรด :-)
15859

6

ฉันรู้คำตอบมากมายอยู่แล้วที่นี่ แต่ไม่มีใครตอบวิธีง่ายๆ เกี่ยวกับเอกสารอย่างเป็นทางการของ fs-exra คุณสามารถทำได้ง่ายมาก

const fs = require('fs-extra')

// copy file
fs.copySync('/tmp/myfile', '/tmp/mynewfile')

// copy directory, even if it has subdirectories or files
fs.copySync('/tmp/mydir', '/tmp/mynewdir')

ตรวจสอบให้แน่ใจว่าได้ตั้งตัวเลือกแบบเรียกซ้ำ fs.copySync ('/ tmp / mydir', '/ tmp / mynewdir', {recursive: true})
Dheeraj Kumar

ฉันไม่พบตัวเลือก{ recursive: true }จากgithub doc ที่คุณพูดถึงไม่ทราบว่ามันใช้งานได้
Freddy Daniel

ฉันเดาว่าเรากำลังพูดถึง fs-extra แต่ลิงก์ github ของคุณชี้ไปที่ node-fs-extra อาจเป็นห้องสมุดที่แตกต่างกัน?
Dheeraj Kumar

@DheerajKumar, มันแสดงให้เห็นโหนด-FS-เสริมใน GitHub แต่ FS-เสริมในNPM ฉันไม่รู้ว่าทั้งสองเหมือนกันโปรดดูแพ็คเกจจากnpm
Freddy Daniel

fs-extra มาแทนที่ fs หรือไม่
แมตต์

4

เนื่องจากฉันเพิ่งสร้างสคริปต์โหนดแบบง่ายฉันไม่ต้องการให้ผู้ใช้สคริปต์ต้องนำเข้าโมดูลและการอ้างอิงภายนอกจำนวนมากดังนั้นฉันจึงใส่ความคิดของฉันและค้นหาการรันคำสั่งจาก bash เปลือก.

ตัวอย่างรหัส node.js นี้คัดลอกโฟลเดอร์ที่ชื่อ node-webkit.app ซ้ำไปยังโฟลเดอร์ที่ชื่อ build:

   child = exec("cp -r node-webkit.app build", function(error, stdout, stderr) {
        sys.print("stdout: " + stdout);
        sys.print("stderr: " + stderr);
        if(error !== null) {
            console.log("exec error: " + error);
        } else {

        }
    });

ขอบคุณแลนซ์พอลลาร์ดที่ dzoneสำหรับการเริ่มต้น

ตัวอย่างด้านบนถูก จำกัด เฉพาะแพลตฟอร์มที่ใช้ Unix เช่น Mac OS และ Linux แต่เทคนิคที่คล้ายกันอาจใช้งานได้กับ Windows


4

@ mallikarjun-m ขอบคุณ!

fs-extraทำสิ่งนั้นและสามารถคืนสัญญาได้หากคุณไม่ได้ให้โทรกลับ! :)

const path = require('path')
const fs = require('fs-extra')

let source = path.resolve( __dirname, 'folderA')
let destination = path.resolve( __dirname, 'folderB')

fs.copy(source, destination)
  .then(() => console.log('Copy completed!'))
  .catch( err => {
    console.log('An error occured while copying the folder.')
    return console.error(err)
  })

2

สิ่งที่สนับสนุนสัญลักษณ์ลิงค์ + จะไม่แสดงหากมีไดเรกทอรีอยู่

function copyFolderSync(from, to) {
  try {
    fs.mkdirSync(to);
  } catch(e) {}

  fs.readdirSync(from).forEach((element) => {
    const stat = fs.lstatSync(path.join(from, element));
    if (stat.isFile()) {
      fs.copyFileSync(path.join(from, element), path.join(to, element));
    } else if (stat.isSymbolicLink()) {
      fs.symlinkSync(fs.readlinkSync(path.join(from, element)), path.join(to, element));
    } else if (stat.isDirectory()) {
      copyFolderSync(path.join(from, element), path.join(to, element));
    }
  });
}

1

รหัสนี้จะใช้งานได้ดีคัดลอกโฟลเดอร์ไปยังตำแหน่งใด ๆ ซ้ำ ๆ ซ้ำ ๆ Windows เท่านั้น

var child=require("child_process");
function copySync(from,to){
    from=from.replace(/\//gim,"\\");
    to=to.replace(/\//gim,"\\");
    child.exec("xcopy /y /q \""+from+"\\*\" \""+to+"\\\"");
}

ทำงานได้อย่างสมบูรณ์แบบสำหรับเกม Text-Based ของฉันเพื่อสร้างผู้เล่นใหม่


1

ฉันพยายาม fs-extra และ copy-dir เพื่อ copy-folder-recursively แต่ฉันต้องการมัน

  1. ทำงานได้ตามปกติ (ตัวคัดลอกผิดพลาดผิดพลาดไม่ได้)
  2. จัดเตรียมอาร์กิวเมนต์สองตัวในตัวกรอง: filepath และ filetype (fs-extra ไม่ได้บอกประเภทไฟล์)
  3. มีการตรวจสอบ dir-to-subdir และการตรวจสอบ dir-to-file

ดังนั้นฉันจึงเขียนของตัวเอง:

//node module for node 8.6+
var path=require("path");
var fs=require("fs");

function copyDirSync(src,dest,options){
  var srcPath=path.resolve(src);
  var destPath=path.resolve(dest);
  if(path.relative(srcPath,destPath).charAt(0)!=".")
    throw new Error("dest path must be out of src path");
  var settings=Object.assign(Object.create(copyDirSync.options),options);
  copyDirSync0(srcPath,destPath,settings);
  function copyDirSync0(srcPath,destPath,settings){
    var files=fs.readdirSync(srcPath);
    if (!fs.existsSync(destPath)) {
      fs.mkdirSync(destPath);
    }else if(!fs.lstatSync(destPath).isDirectory()){
      if(settings.overwrite)
        throw new Error(`Cannot overwrite non-directory '${destPath}' with directory '${srcPath}'.`);
      return;
    }
    files.forEach(function(filename){
      var childSrcPath=path.join(srcPath,filename);
      var childDestPath=path.join(destPath,filename);
      var type=fs.lstatSync(childSrcPath).isDirectory()?"directory":"file";
      if(!settings.filter(childSrcPath,type))
        return;
      if (type=="directory") {
        copyDirSync0(childSrcPath,childDestPath,settings);
      } else {
        fs.copyFileSync(childSrcPath, childDestPath, settings.overwrite?0:fs.constants.COPYFILE_EXCL);
        if(!settings.preserveFileDate)
          fs.futimesSync(childDestPath,Date.now(),Date.now());
      }
    });
  }
}
copyDirSync.options={
  overwrite: true,
  preserveFileDate: true,
  filter: function(filepath,type){return true;}
};

และฟังก์ชั่นที่คล้ายกัน mkdirs ซึ่งเป็นทางเลือกให้ mkdirp

function mkdirsSync(dest) {
  var destPath=path.resolve(dest);
  mkdirsSync0(destPath);
  function mkdirsSync0(destPath){
    var parentPath=path.dirname(destPath);
    if(parentPath==destPath)
      throw new Error(`cannot mkdir ${destPath}, invalid root`);
    if (!fs.existsSync(destPath)) {
      mkdirsSync0(parentPath);
      fs.mkdirSync(destPath);
    }else if(!fs.lstatSync(destPath).isDirectory()){
      throw new Error(`cannot mkdir ${destPath}, a file already exists there`);
    }
  }
}

0

ฉันเขียนฟังก์ชันนี้สำหรับทั้งการคัดลอก (copyFileSync) หรือการย้าย (renameSync) ไฟล์ซ้ำระหว่างไดเรกทอรี:

//copy files
copyDirectoryRecursiveSync(sourceDir, targetDir);
//move files
copyDirectoryRecursiveSync(sourceDir, targetDir, true);


function copyDirectoryRecursiveSync(source, target, move) {
if (!fs.lstatSync(source).isDirectory()) return;

var operation = move ? fs.renameSync : fs.copyFileSync;
fs.readdirSync(source).forEach(function (itemName) {
    var sourcePath = path.join(source, itemName);
    var targetPath = path.join(target, itemName);

    if (fs.lstatSync(sourcePath).isDirectory()) {
        fs.mkdirSync(targetPath);
        copyDirectoryRecursiveSync(sourcePath, targetDir);
    }
    else {
        operation(sourcePath, targetPath);
    }
});}

0

หากคุณอยู่ใน Linux และประสิทธิภาพไม่ใช่ปัญหาคุณอาจใช้execฟังก์ชันจากchild_processโมดูลเพื่อดำเนินการคำสั่ง bash:

const { exec } = require('child_process');
exec('cp -r source dest', (error, stdout, stderr) => {...});

ในบางกรณีฉันพบว่าวิธีนี้สะอาดกว่าการดาวน์โหลดโมดูลทั้งหมดหรือแม้กระทั่งการใช้fsโมดูล


0

ncpล็อคไฟล์ descriptor และ fires callback เมื่อมันยังไม่ถูกปลดล็อค ฉันแนะนำให้ใช้โมดูลการคัดลอกซ้ำซ้ำ สนับสนุนกิจกรรมและคุณมั่นใจได้ในตอนจบการคัดลอก


0

ระวังเมื่อเลือกแพ็คเกจของคุณ บางแพ็คเกจเช่น copy-dir ไม่รองรับการคัดลอกไฟล์ขนาดใหญ่ที่มีความยาวมากกว่า 0x1fffffe8 ตัวอักษร มันจะทำให้เกิดข้อผิดพลาดบางอย่างเช่น:

buffer.js:630 Uncaught Error: Cannot create a string longer than 0x1fffffe8 characters 

ฉันเคยมีประสบการณ์เช่นนี้ในหนึ่งในโครงการของฉัน ท้ายที่สุดฉันต้องเปลี่ยนแพ็คเกจที่ฉันใช้และปรับรหัสให้มาก ฉันจะบอกว่านี่ไม่ใช่ประสบการณ์ที่น่าพอใจมาก

หากต้องการแหล่งที่มาหลายแห่งและคัดลอกปลายทางหลายปลายทางคุณสามารถใช้สำเนาที่ดีกว่าและเขียนดังนี้:

// copy from multiple source into a directory
bCopy(['/path/to/your/folder1', '/path/to/some/file.txt'], '/path/to/destination/folder');

หรือแม้กระทั่ง :

// copy from multiple source into multiple destination
bCopy(['/path/to/your/folder1', '/path/to/some/file.txt'], ['/path/to/destination/folder', '/path/to/another/folder']);

-1

ใช่ncpเป็นcoolแต่ ...

คุณอาจต้องการ / ควร promisify super coolฟังก์ชั่นที่จะทำให้เป็น เนื่องจากคุณอยู่ที่นี่ให้เพิ่มลงในtoolsไฟล์เพื่อนำมาใช้ซ้ำ

ด้านล่างนี้เป็นรุ่นที่ทำงานซึ่งเป็นและการใช้งานAsyncPromises


index.js

const {copyFolder} = require('./tools/');

return copyFolder(
    yourSourcePath,
    yourDestinationPath
)
.then(() => {
    console.log('-> Backup completed.')
}) .catch((err) => {
    console.log("-> [ERR] Could not copy the folder: ", err);
})

tools.js

const ncp = require("ncp");

/**
 * Promise Version of ncp.ncp()
 * 
 * This function promisifies ncp.ncp().
 * We take the asynchronous function ncp.ncp() with 
 * callback semantics and derive from it a new function with
 * promise semantics.
 */
ncp.ncpAsync = function (sourcePath, destinationPath) {
  return new Promise(function (resolve, reject) {
      try {
          ncp.ncp(sourcePath, destinationPath, function(err){
              if (err) reject(err); else resolve();
          });
      } catch (err) {
          reject(err);
      }
  });
};

/**
 * Utility function to copy folders asynchronously using
 * the Promise returned by ncp.ncp(). 
 */
const copyFolder = (sourcePath, destinationPath) => {
    return ncp.ncpAsync(sourcePath, destinationPath, function (err) {
        if (err) {
            return console.error(err);
        }
    });
}
module.exports.copyFolder = copyFolder;

-1

วิธีที่ง่ายที่สุดสำหรับปัญหานี้คือการใช้เฉพาะโมดูล 'fs' และ 'เส้นทาง' และตรรกะบางอย่าง .....

ไฟล์ทั้งหมดในสำเนาโฟลเดอร์รากด้วยชื่อใหม่หากคุณต้องการเพียงแค่ตั้งหมายเลขเวอร์ชั่นเช่น ....................... "var v = 'ไดเรกทอรีของคุณ ชื่อ'"

ในคำนำหน้าชื่อไฟล์เนื้อหา V ที่เพิ่มด้วยชื่อไฟล์

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

var c = 0;
var i =0 ;
var v = "1.0.2";
var copyCounter = 0;
var directoryCounter = 0; 
var directoryMakerCounter = 0;
var recursionCounter = -1;
var Flag = false;
var directoryPath = [] ;
var directoryName = [] ;
var directoryFileName = [];
var fileName;
var directoryNameStorer;
var dc = 0;
var route ;



if (!fs.existsSync(v)){
   fs.mkdirSync(v);
}

var basePath = path.join(__dirname, v);


function walk(dir){

  fs.readdir(dir, function(err, items) {

    items.forEach(function(file){

        file = path.resolve(dir, file);

        fs.stat(file, function(err, stat){
            if(stat && stat.isDirectory()){

                directoryNameStorer = path.basename(file);
                route = file;
                route = route.replace("gd",v);

                directoryFileName[directoryCounter] = route;
                directoryPath[directoryCounter] = file;
                directoryName[directoryCounter] = directoryNameStorer;

                directoryCounter++;
                dc++;

                if (!fs.existsSync(basePath+"/"+directoryName[directoryMakerCounter])){
                    fs.mkdirSync(directoryFileName[directoryMakerCounter]);
                    directoryMakerCounter++;
                }

            }else{

                    fileName = path.basename(file);
                    if(recursionCounter >= 0){
                        fs.copyFileSync(file, directoryFileName[recursionCounter]+"/"+v+"_"+fileName, err => {
                            if(err) return console.error(err);
                        });
                        copyCounter++;
                    }else{
                        fs.copyFileSync(file, v+"/"+v+"_"+fileName, err => {
                            if(err) return console.error(err);
                        });
                        copyCounter++;    
                    }

                }
                if(copyCounter + dc == items.length && directoryCounter > 0 && recursionCounter < directoryMakerCounter-1){
                    console.log("COPY COUNTER :             "+copyCounter);
                    console.log("DC COUNTER :               "+dc);                        
                    recursionCounter++;
                    dc = 0;
                    copyCounter = 0;
                    console.log("ITEM DOT LENGTH :          "+items.length);
                    console.log("RECURSION COUNTER :        "+recursionCounter);
                    console.log("DIRECOTRY MAKER COUNTER :  "+directoryMakerCounter);
                    console.log(": START RECURSION :        "+directoryPath[recursionCounter]);
                    walk(directoryPath[recursionCounter]); //recursive call to copy sub-folder

                }

        })
    })
 });

}
 walk('./gd', function(err, data){ //Just Pass The Root Directory Which You Want to Copy
 if(err) throw err;
 console.log("done");
})

-1

นี่คือวิธีที่ฉันทำ:

let fs = require('fs');
let path = require('path');

แล้ว:

let filePath = //your FilePath

let fileList = []
        var walkSync = function(filePath, filelist) 
        {
          let files = fs.readdirSync(filePath);
          filelist = filelist || [];
          files.forEach(function(file) 
          {
            if (fs.statSync(path.join(filePath, file)).isDirectory()) 
            {
              filelist = walkSync(path.join(filePath, file), filelist);
            }
            else 
            {
              filelist.push(path.join(filePath, file));
            }
          });

          // Ignore hidden files
          filelist = filelist.filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));

          return filelist;
        };

จากนั้นเรียกเมโทด:

This.walkSync(filePath, fileList)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.