2016-10-27 5 views
6

は、私たちがこのようなプログラムがあるとします。同じファイルに複数のfs.writeを追加して実行の順序を保証できますか?

// imagine the string1 to string1000 are very long strings, which will take a while to be written to file system 
var arr = ["string1",...,"string1000"]; 
for (let i = 1; i < 1000; i++) { 
    fs.write("./same/path/file.txt", arr[i], {flag: "a"}}); 
} 

私の質問は本当に実行される)fs.writeは非同期関数であるので、私は、それぞれが(fs.writeするために呼び出す方法がわからない、will string1 to string1000 be gurantted to append to the same file in order?

です。私は各文字列のための関数の呼び出しは、callstackのようなanother threadのどこかに置く必要があり、前回の呼び出しが完了すると次の呼び出しを実行できると仮定します。

私の理解が正確であるかどうかはわかりません。コメントと回答のように

編集1

、私はfs.writecallbackを待たずに同じファイルに複数の書き込みのために安全ではありません参照してください。しかし、書き込みストリームについてはどうですか?

次のコードを使用すると、書面の順序が保証されますか?

// imagine the string1 to string1000 are very long strings, which will take a while to be written to file system 
var arr = ["string1",...,"string1000"]; 
var fileStream = fs.createWriteFileStream("./same/path/file.txt", { "flags": "a+" }); 
for (let i = 1; i < 1000; i++) { 
    fileStream.write(arr[i]); 
} 
fileStream.on("error",() => {// do something}); 
fileStream.on("finish",() => {// do something}); 
fileStream.end(); 

コメントや修正は参考になります。ありがとう!

+1

を読むことができます) '(https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback)、ドキュメントには、「同じファイルに対して' fs.writeFile'を何度も使用するのは安全ではありませんコールバック "_。 – robertklep

+0

node.jsでのバッファリングの仕組みにより、コールバックを待つことなく、順序や書き込みに影響を与えないことに注意してください。安全でないのは、バッファオーバーフローの可能性です。だから、リスクは書き込みがなくなっていて、順序付けされていない書き込みではありません。 – slebetman

+0

@slebetman、返信ありがとうございます。しかし、ここでバッファーとはどういう意味ですか? – Lubor

答えて

4

docsは、コールバックを待たずに、同じファイルにfs.writeを複数回使用することが安全でないことを

注意と言います。このシナリオでは、fs.createWriteStreamを強くお勧めします。

ストリームは、ストリームに書き込まれる文字列の順序が本質的に読み出される順番であることを保証するため、ストリームを使用すると機能します。まだfs.writeを使用するだけでなく、物事がために起こることを確認するために

var stream = fs.createWriteStream("./same/path/file.txt"); 
stream.on('error', console.error); 
arr.forEach((str) => { 
    stream.write(str + '\n'); 
}); 
stream.end(); 

もう一つの方法は、順次論理を維持するための約束を使用することです。

function writeToFilePromise(str) { 
    return new Promise((resolve, reject) => { 
    fs.write("./same/path/file.txt", str, {flag: "a"}}, (err) => { 
     if (err) return reject(err); 
     resolve(); 
    }); 
    }); 
} 

// for every string, 
// write it to the file, 
// then write the next one once that one is finished and so on 
arr.reduce((chain, str) => { 
    return chain 
    .then(() => writeToFilePromise(str)); 
}, Promise.resolve()); 
+0

次にcreateWriteFileStreamはどうなりますか?ファイルストリームを使用している場合は、注文を保証できますか? – Lubor

+0

@Luborは私の編集をチェックアウト – nem035

+0

ありがとう!しかし、stream.write(str)は同期操作であると言っていますか?私はこれを非同期として考えています。 – Lubor

0

あなたはノードのロック読み取り/書き込みを使用してファイルへのアクセスを同期させることができ、以下の例を参照してください。ANあなたは `fs.writeFile([意味場合はdocumentation

var ReadWriteLock = require('rwlock'); 

var lock = new ReadWriteLock(); 

lock.writeLock(function (release) { 
    fs.appendFile(fileName, addToFile, function(err, data) { 
    if(err) 
     console.log("write error); 
    else  
     console.log("write ok"); 

    release(); // unlock 
    });  
}); 
関連する問題