私が取り組んでいるプロジェクト(node.js)は、ファイルシステムでの多くの操作(コピー/読み取り/書き込みなど)を意味します。どの方法が最速か知りたいのですが、アドバイスをいただければ幸いです。ありがとう。
私が取り組んでいるプロジェクト(node.js)は、ファイルシステムでの多くの操作(コピー/読み取り/書き込みなど)を意味します。どの方法が最速か知りたいのですが、アドバイスをいただければ幸いです。ありがとう。
回答:
これは、ストリームを使用して1行のコードでファイルをコピーするのに適した方法です。
var fs = require('fs');
fs.createReadStream('test.log').pipe(fs.createWriteStream('newLog.log'));
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');
});
createReadStream
との両方のcreateWriteStream
エラーをチェックする必要があるので、ワンライナーは得られないことを覚えておいてください(それでも速度は同じです)。
cp test.log newLog.log
viaを実行するよりもどのくらい速く/遅くなりrequire('child_process').exec
ますか?
copy
、完全なNode.jsソリューションとは異なり、Windowには移植できません。
child_process.execFile('/bin/cp', ['--no-target-directory', source, target])
ます。
fs.createReadStream('./init/xxx.json').pipe(fs.createWriteStream('xxx.json'));
同じメカニズムですが、これによりエラー処理が追加されます。
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;
}
}
}
WriteStream
をアンパイプするだけだと思います。あなたはrd.destroy()
自分を呼ばなければならないでしょう。少なくともそれが私に起こったことです。悲しいことに、ソースコード以外のドキュメントはあまりありません。
cb
略ですか?3番目の引数として何を渡すべきですか?
createReadStream/createWriteStream
何らかの理由でメソッドを機能させることができませんでしたが、fs-extra
npmモジュールを使用すると、すぐに機能しました。ただし、パフォーマンスの違いはわかりません。
npm install --save fs-extra
var fs = require('fs-extra');
fs.copySync(path.resolve(__dirname,'./init/xxx.json'), 'xxx.json');
fs.copy(src, dst, callback);
、これらは@mvillarの懸念を解決するはずです。
Node.jsの8.5.0以来、私たちは新しい持っfs.copyFileとfs.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');
});
copyFile()
より長いファイルを上書きしている間はバグがあることに注意してください。uv_fs_copyfile()
Node v8.7.0(libuv 1.15.0)までの礼儀。github.com/libuv/libuv/pull/1552を
プロミスとエラー管理を備えた、書き込みが高速で使いやすい。
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;
}
}
new Promise(function(resolve, reject) { resolve(1); resolve(2); reject(3); reject(4); console.log("DONE"); }).then(console.log.bind(console), function(e){console.log("E", e);});
して仕様を調べましたが、あなたは正しいです:解決された約束を解決または拒否しようとしても効果はありません。おそらくあなたはあなたの答えを拡張して、なぜあなたがこのように関数を書いたのかを説明できますか?ありがとう:-)
close
はずfinish
です。
/dev/stdin
、それはバグですgithub.com/joyent/node/issues/25375
まあ、通常は非同期のファイル操作を避けるのが良いでしょう。以下は、短い(つまり、エラー処理を行わない)同期の例です。
var fs = require('fs');
fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));
*Sync
メソッドの使用は、nodejsの哲学に完全に反します!また、これらは徐々に廃止されていると思います。nodejsの全体的な考え方は、それがシングルスレッドでイベント駆動型であるということです。
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) {
var data = fs.readFileSync(src);
fs.writeFileSync(dest, data);
}
fs.existsSync
呼び出しは省略されなければなりません。fs.existsSync
通話と通話の間にファイルが消える可能性がありますfs.readFileSync
。つまり、fs.existsSync
通話は何からも保護されません。
false
場合はfs.existsSync
失敗する可能性があるの少数の消費者が悪いために人間工学は、copySync
任意のより多くの我々が行うよりも、手動で戻り値にそれが呼ばれていますたびに検査することだと思いますfs.writeFileSync
ら。。例外を投げることが実際に望ましいです。
const fs = require("fs");
fs.copyFileSync("filepath1", "filepath2"); //fs.copyFileSync("file1.txt", "file2.txt");
これは私が個人的にファイルをコピーし、node.jsを使用して別のファイルを置き換えるために使用するものです:)
高速コピーには、fs.constants.COPYFILE_FICLONE
フラグを使用する必要があります。(これをサポートするファイルシステムの場合)実際にはファイルの内容をコピーしないようにすることができます。新しいファイルエントリが作成されるだけですが、それはソースファイルのコピーオンライト「クローン」を指します。
何もしない/少ないことは、何かをする最も速い方法です;)
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");
}
);
代わりにpromiseを使用する:
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.promises.copyFile
コピーの前にファイルの可視性をチェックする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);
}
});
});
}
コピー機能に組み込まれた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
マイクのソリューション、ただし約束あり:
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);
});
};
他の1つの答えの改善。
特徴:
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);
}
ソースファイルの存在をチェックしない上記のすべてのソリューションは危険です...例
fs.stat(source, function(err,stat) { if (err) { reject(err) }
そうしないと、ソースとターゲットが誤って置き換えられた場合にシナリオにリスクが生じ、エラーに気付かずにデータが完全に失われます。