手動の手順を実行せずに、フォルダとそのすべてのコンテンツをコピーする簡単な方法がありfs.readir、fs.readfile、fs.writefile再帰的には?
理想的にはこのように機能する関数が欠けているのかと思っているだけです
fs.copy("/path/to/source/folder","/path/to/destination/folder");
手動の手順を実行せずに、フォルダとそのすべてのコンテンツをコピーする簡単な方法がありfs.readir、fs.readfile、fs.writefile再帰的には?
理想的にはこのように機能する関数が欠けているのかと思っているだけです
fs.copy("/path/to/source/folder","/path/to/destination/folder");
回答:
npm install ncpそして30代未満で働いています。ありがとう。
これは、追加のモジュールなしでこの問題を解決するための私のアプローチです。ビルトイン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 );
}
} );
}
}
javascript var fs = require('fs'); var path = require('path');
fs.copyかfs.copySync、実際に呼び出す必要があるため、実際にファイルをコピーします。
fs.copyFile、MacとWindowsでノードソースを確認すると、OS固有の関数を呼び出してファイルをコピーします
コンテンツを含むフォルダのコピーをサポートするいくつかのモジュールがあります。最も人気があるのはレンチでしょう
// Deep-copy an existing directory
wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');
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
ディレクトリとその内容を別のディレクトリに再帰的にコピーする関数を次に示します。
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);
}
};
fs.lstatSync代わりに使用fs.statSync)
linkingコピーしていない..問題は、リンクされたファイルのコンテンツを変更すると、元のファイルも変更されることです。
fs-extraとき私のために働いたncpとwrench下回りました:
wrenchしたためfs-extra、ユーザーに使用を指示しています。
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}`);
それでおしまい!
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
これは私が個人的に行う方法です:
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));
}
});
}
フォルダとファイルで機能します
(ncpを使用した@ shift66の回答に基づいて)ほんの数ステップでソースフォルダーを別の宛先フォルダーにコピーする小さな作業例を作成しました。
ステップ1-ncpモジュールをインストールします。
npm install ncp --save
ステップ2-copy.jsを作成します(srcPathとdestPathの変数を必要に応じて変更します):
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
これはノード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存在しないことを前提としています。
require('util').promisifyします。fs.mkdirfs.copyFilerequire('fs').promises
withFileTypesオプションがありますか?stat通話を節約できるため
withFileTypesオプションがありません。
私はすでにここで多くの答えを知っていますが、誰もそれを簡単な方法で答えませんでした。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')
単純なノードスクリプトを作成しているだけなので、スクリプトのユーザーが外部モジュールと依存関係の束をインポートする必要がないようにしたいので、思考の上限を設定し、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のLance Pollardに感謝します。
上記のスニペットは、Mac OSやLinuxなどのUnixベースのプラットフォームに限定されていますが、Windowsでも同様の手法が機能する場合があります。
@ mallikarjun-mありがとうございます!
fs-extraが処理を行い、コールバックを提供しない場合はPromiseを返すこともできます!:)
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)
})
1 シンボリックリンクのサポートディレクトリが存在する場合は+がスローされません。
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));
}
});
}
このコードは問題なく機能し、任意のフォルダを任意の場所に再帰的にコピーします。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+"\\\"");
}
新しいプレーヤーを作成するためのテキストベースのゲームに最適です。
fs-extraとcopy-dirをcopy-folder-recursivelyに試しました。でも欲しい
だから私は自分で書きました:
//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;}
};
mkdirpの代替となる同様の関数mkdirs
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`);
}
}
}
この関数は、ディレクトリ間でファイルを再帰的にコピー(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);
}
});}
Linuxを使用していてパフォーマンスに問題がない場合は、モジュールのexec関数を使用しchild_processてbashコマンドを実行できます。
const { exec } = require('child_process');
exec('cp -r source dest', (error, stdout, stderr) => {...});
場合によっては、モジュール全体をダウンロードしたり、モジュールを使用したりするよりも、このソリューションの方がきれいであることがわかりましたfs。
ncpはファイル記述子をロックし、まだロック解除されていないときにコールバックを起動します。代わりに再帰コピーモジュールを使用することをお勧めします。イベントに対応しており、確実にコピー終了となります。
パッケージを選ぶときは注意してください。copy-dirのような一部のパッケージでは、0x1fffffe8文字を超える大きなファイルのコピーはサポートされていません。次のようなエラーがスローされます:
buffer.js:630 Uncaught Error: Cannot create a string longer than 0x1fffffe8 characters
私は自分のプロジェクトの1つでこのようなことを経験しました。最終的に、使用しているパッケージを変更し、多くのコードを調整する必要がありました。これはとても楽しい経験ではないと思います。
複数のコピー元と複数のコピー先が必要な場合は、より良いコピーを使用して、次のように記述できます。
// 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']);
ncpですcoolけれども...あなたはその機能を約束することを望む/すべきsuper coolです:あなたはそれをやっているので、それをtoolsファイルに追加して再利用します。
以下は作業バージョンであるAsyncと用途はPromises。
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;
この問題に対する最も簡単なアプローチは、「fs」および「Path」モジュールといくつかのロジックのみを使用することです。
バージョン番号を設定したいだけの場合は、ルートフォルダー内のすべてのファイルが新しい名前でコピーされます。つまり、............ "" var v = 'Your Directory名前'"
ファイル名のプレフィックス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");
})
これは私がやった方法です:
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)