回答:
時々追加する場合は、を使用できますappendFile。これにより、呼び出されるたびに新しいファイルハンドルが作成されます。
非同期に:
const fs = require('fs');
fs.appendFile('message.txt', 'data to append', function (err) {
if (err) throw err;
console.log('Saved!');
});
同期的に:
const fs = require('fs');
fs.appendFileSync('message.txt', 'data to append');
process.exit()直後にfs.appendFileある場合、出力が送信される前に終了できます。(使用returnは問題あり
appendFileSync。nodejs.org/api/…しかし、非同期操作であるNodeの大きな利点の1つを失う可能性があります。エラーを確実にキャッチしてください。おそらく一部のOSでは、同時にファイルハンドルを要求すると、アクセスが拒否される可能性があります。わからない
ログファイルに書き込む場合、つまりファイルの最後にデータを追加する場合は、を使用しないでくださいappendFile。appendFileしばらくすると、美しいEMFILEエラーが発生し、ファイルに追加する各データのファイルハンドルが開きます。
追加することappendFileができWriteStreamます。
の例appendFile:
console.log(new Date().toISOString());
[...Array(10000)].forEach( function (item,index) {
fs.appendFile("append.txt", index+ "\n", function (err) {
if (err) console.log(err);
});
});
console.log(new Date().toISOString());
私のコンピューターでは最大8000です。ファイルにデータを追加すると、次のようになります。
{ Error: EMFILE: too many open files, open 'C:\mypath\append.txt'
at Error (native)
errno: -4066,
code: 'EMFILE',
syscall: 'open',
path: 'C:\\mypath\\append.txt' }
さらに、appendFile有効にすると書き込みが行われるため、ログはタイムスタンプで書き込まれません。たとえば、100000の代わりに1000を設定してテストできます。順序はランダムになり、ファイルへのアクセスに依存します。
ファイルに追加する場合は、次のような書き込み可能なストリームを使用する必要があります。
var stream = fs.createWriteStream("append.txt", {flags:'a'});
console.log(new Date().toISOString());
[...Array(10000)].forEach( function (item,index) {
stream.write(index + "\n");
});
console.log(new Date().toISOString());
stream.end();
あなたがしたいときにそれを終了します。を使用する必要はありませんstream.end()。デフォルトのオプションはAutoClose:trueなので、プロセスが終了するとファイルは終了し、あまりにも多くのファイルを開かないようにします。
stream.end()前に実行されるstream.write()ので、私たちは使用すべきではないのでstream.end()、あなたが言及したように、それAutoClose:Trueはデフォルトのオプションであり、そしてなぜわからない行を書くのか使用する。
due to asynchronous nature of Javascript... 何?Array.forEachは同期操作です。JSは同期です。たまたま、Promiseやasync / awaitなどの非同期操作を管理するいくつかの方法が提供されます。
fs.appendFile非同期で実行するため、開いているファイルが多すぎると思います(非同期に10000のファイルハンドルを作成しているだけです)。appendFileSync同様の問題はなくfs.appendFile、適切な間隔(1秒はおそらく十分すぎる)ではないと思います。またはキューイング。
createWriteStreamを使用するコードは、書き込みごとにファイル記述子を作成します。log.endは、書き込みの直後にノードに閉じるように要求するため、より優れています。
var fs = require('fs');
var logStream = fs.createWriteStream('log.txt', {flags: 'a'});
// use {flags: 'a'} to append and {flags: 'w'} to erase and write a new file
logStream.write('Initial line...');
logStream.end('this is the end line');
var fs = require('graceful-fs')、いくつかの既知の問題を明らかにした、さらに良いかもしれません。詳しくはドキュメントをご覧ください。
fs.createWriteStream、を使用してくださいflags。あなたが使用している場合fs.writeFileはそれflagです。詳細については、Node JS Docs-File Systemを参照してください。
に加えて、既存のファイルにデータを追加するためにappendFileフラグを渡すこともできwriteFileます。
fs.writeFile('log.txt', 'Hello Node', {'flag':'a'}, function(err) {
if (err) {
return console.error(err);
}
});
フラグ 'a'を渡すと、データがファイルの最後に追加されます。
fs.createWriteStream、を使用してくださいflags。あなたが使用している場合fs.writeFileはそれflagです。詳細については、Node JS Docs-File Systemを参照してください。
それを開いてから書き込む必要があります。
var fs = require('fs'), str = 'string to append to file';
fs.open('filepath', 'a', 666, function( e, id ) {
fs.write( id, 'string to append to file', null, 'utf8', function(){
fs.close(id, function(){
console.log('file closed');
});
});
});
パラメータを説明するのに役立ついくつかのリンクがあります
編集:この回答は無効になりました。追加するための新しいfs.appendFileメソッドを調べてください。
Node.js 0.8にはfs.appendFile:
fs.appendFile('message.txt', 'data to append', (err) => {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
fd = fs.openSync(path.join(process.cwd(), 'log.txt'), 'a')
fs.writeSync(fd, 'contents to append')
fs.closeSync(fd)
ファイルに1行ずつログを書き込む簡単でストレスのない方法が必要な場合は、fs-extraをお勧めします。
const os = require('os');
const fs = require('fs-extra');
const file = 'logfile.txt';
const options = {flag: 'a'};
async function writeToFile(text) {
await fs.outputFile(file, `${text}${os.EOL}`, options);
}
writeToFile('First line');
writeToFile('Second line');
writeToFile('Third line');
writeToFile('Fourth line');
writeToFile('Fifth line');
ノードv8.9.4でテスト済み。
私のアプローチはかなり特別です。私は基本的にWriteStreamソリューションを使用しますが、を使用してfdを実際に「閉じる」ことはありませんstream.end()。代わりにcork/ を使用しますuncork。これは、RAM使用量が少ないというメリットがあり(それが重要な場合)、ロギング/レコーディングに使用する方が安全だと思います(私の元の使用例)。
以下はかなり単純な例です。forショーケースに疑似ループを追加しただけであることに注意してください。本番コードでは、WebSocketメッセージを待機しています。
var stream = fs.createWriteStream("log.txt", {flags:'a'});
for(true) {
stream.cork();
stream.write("some content to log");
process.nextTick(() => stream.uncork());
}
uncork 次のティックでデータをファイルにフラッシュします。
私のシナリオでは、さまざまなサイズで1秒あたり最大200回の書き込みのピークがあります。ただし、夜間は1分あたり数回の書き込みのみが必要です。コードはピーク時にも非常に信頼性の高い動作をします。
私は、オープンフラグを制御が便利な場合がありますという理由だけで、この提案を提供し、例えば、あなたが最初にそれを既存のファイルを切り捨て、したいことがあり、その後、それへの書き込みのシリーズを追加-フラグ「W」、その場合、使用中のファイルを開くときすべての書き込みが完了するまで閉じないでください。もちろんappendFileはあなたが望んでいるものかもしれません:-)
fs.open('log.txt', 'a', function(err, log) {
if (err) throw err;
fs.writeFile(log, 'Hello Node', function (err) {
if (err) throw err;
fs.close(log, function(err) {
if (err) throw err;
console.log('It\'s saved!');
});
});
});
ファイルに何かを追加する必要があるfs.appendFile場合fsPromises.appendFileは、or を使用するのが最も速く、最も堅牢なオプションです。
提案されたいくつかの回答とは対照的に、ファイルパスがappendFile関数に提供されている場合、 実際にはそれ自体が閉じます。あなたがファイルハンドルを渡すときだけ、あなたfs.open()はそれを閉じるような世話をしなければならないようなものを手に入れます。
ファイルに50,000行以上を入れてみました。
例:
(async () => {
// using appendFile.
const fsp = require('fs').promises;
await fsp.appendFile(
'/path/to/file', '\r\nHello world.'
);
// using apickfs; handles error and edge cases better.
const apickFileStorage = require('apickfs');
await apickFileStorage.writeLines(
'/path/to/directory/', 'filename', 'Hello world.'
);
})();
参照:https
: //github.com/nodejs/node/issues/7560
実行例:https : //github.com/apickjs/apickFS/blob/master/writeLines.js
これが完全なスクリプトです。ファイル名を入力して実行すると、問題なく機能するはずです。これは、スクリプトの背後にあるロジックに関するビデオチュートリアルです。
var fs = require('fs');
function ReadAppend(file, appendFile){
fs.readFile(appendFile, function (err, data) {
if (err) throw err;
console.log('File was read');
fs.appendFile(file, data, function (err) {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
});
}
// edit this with your file names
file = 'name_of_main_file.csv';
appendFile = 'name_of_second_file_to_combine.csv';
ReadAppend(file, appendFile);
これを行う簡単な方法は
const fs = require('fs');
fs.appendFileSync('file.txt', 'message to append into file');
appendFileSync解決策を与える一番上の答えを確認しましたか?
const inovioLogger = (logger = "") => {
const log_file = fs.createWriteStream(__dirname + `/../../inoviopay-${new Date().toISOString().slice(0, 10)}.log`, { flags: 'a' });
const log_stdout = process.stdout;
log_file.write(logger + '\n');
}
denysoniqueの回答に加えてappendFile、コールバックの受け渡しではなくpromiseが返されるNodeJSの非同期タイプやその他の非同期メソッドが使用される場合があります。これを行うには、promisifyHOFで関数をラップするか、Promise名前空間から非同期関数をインポートする必要があります。
const { appendFile } = require('fs').promises;
await appendFile('path/to/file/to/append', dataToAppend, optionalOptions);
お役に立てれば幸いです😉