2

node.js/socket.io を学ぼうとして、クライアント ブラウザーからデータ チャンクを取得し、サーバー側で再構築する単純なファイル アップローダーの作成に取り掛かりました。

チャンクを受信するための socket.io イベントは次のようになります。

socket.on('sendChunk', function (data) {
    fs.appendFile(path + fileName, data.data, function (err) {
      if (err) 
       throw err;
      console.log(data.sequence + ' - The data was appended to file ' + fileName);
    });
  });

問題は、非同期呼び出しが原因で、データ チャンクが必ずしも受信した順序で追加されるとは限らないことです。典型的なコンソール出力は次のようになります。

  • 1 - データはファイル testfile.txt に追加されました
  • 3 - データはファイル testfile.txt に追加されました
  • 4 - データはファイル testfile.txt に追加されました
  • 2 - データはファイル testfile.txt に追加されました

私の質問は、この機能をブロックしない方法で実装し、シーケンスを強制する適切な方法は何ですか。私はasyncのようなライブラリを見てきましたが、シリーズを作成してすべてのファイルチャンクが入ったら実行するのではなく、入ってくるたびにそれぞれを処理できるようにしたいと思っています。 、だからどんなポインタも素晴らしいです。

4

2 に答える 2

4

通常、書き込み待ちのデータにはキューを使用し、前の追加が終了するたびに、次のピースを書き込もうとします。このようなもの:

var parts = [];
var inProgress = false;
function appendPart(data){
  parts.push(data);
  writeNextPart();
}

function writeNextPart(){
  if (inProgress || parts.length === 0) return;

  var data = parts.shift();
  inProgress = true;
  fs.appendFile(path + fileName, data.data, function (err) {
    inProgress = false;
    if (err) throw err;
    console.log(data.sequence + ' - The data was appended to file ' + fileName);

    writeNextPart();
  });
}

socket.on('sendChunk', function (data) {
  appendPart(data);
});

partsファイル名にinProgress基づいてキューを保持するには、これを拡張する必要があります。私の例では、単純化のためにそれらが一定であると想定しています。

于 2013-02-17T03:28:39.697 に答える
0

追加を順番にまたは同期する必要があるためです。fs.appendFileSyncの代わりに使用できますfs.appendFile。これは最も手っ取り早い方法ですが、パフォーマンスが低下します。

自分で非同期に処理したい場合は、 を使用してこの問題を処理するストリームを使用してEventEmitterください。応答 (および要求) オブジェクトがストリームであることがわかります。で書き込み可能なストリームを作成しfs.createWriteStream、ファイルを追加するすべての部分を書き込みます。

fs.createWriteStream(path, [options])#
Returns a new WriteStream object (See Writable Stream).

options is an object with the following defaults:

{ flags: 'w',
  encoding: null,
  mode: 0666 }

あなたの場合、フラグを使用します:「a」

于 2013-02-17T15:59:44.750 に答える