3

以前の質問fs.createReadStream()では、node.js でファイルからランダム アクセス読み取りを行う唯一の方法は、オプションfdの 、start、およびendフィールドを使用することであると思われました。

これは、私の最も単純なテストではうまくいきました。しかし、私のプロジェクトでは、バイナリ ファイルのさまざまなオフセットから繰り返し読み取る必要があります。これは奇妙な方法で失敗したので、最小限のテスト ケースを考え出しました。

var fs = require('fs');

fs.open('test.txt', 'r', function (err, fd) {
  if (err) {
    console.error('error opening file: ' + err);
  } else {
    fs.createReadStream(null, {fd: fd, start: 2, end: 5}).on('error', function (err) {
        throw e;
      }).on('close', function () {
        console.log('outer close');
      }).on('data', function (data) {
        console.log('outer data', data);
      }).on('end', function () {
        console.log('outer end');

        fs.createReadStream(null, {fd: fd, start: 0, end: 3}).on('error', function (err) {
            throw e;
          }).on('close', function () {
            console.log('inner close');
          }).on('data', function (data) {
            console.log('inner data', data);
          }).on('end', function () {
            console.log('inner end');

            // more code to execute after both reads
          });
      });
  }
});

内部endイベントは受信されません。(アウターcloseはバラバラに入荷していますが、コードを付ける必要はありません。)

このプロジェクトは以前に Perl で実装したこともあり、Firefox 拡張機能として JavaScript で実装したこともありますが、node の下では難しいことがわかりました。これは、汎用スクリプト言語として node.js を使い始めることができるかどうかのテストでもあります。

4

1 に答える 1

3

問題は、外側が使用後にReadStream閉じるfdため、2 番目に再使用するReadStreamと失敗することです。最新の Node 不安定版には実際にはautoCloseオプションがありますReadStreamsが、それはまだ安定版の一部ではありません。

本当の答えは、前の質問で提供された情報が間違っているということです。createReadStreamはすべて公開 API を使用して実装されているため、できることとできないことはありません。この場合、fs.readそのposition引数とともに使用できます。

var fs = require('fs');                                                         

fs.open('test.txt', 'r', function (err, fd) {                                   
  if (err) {                                                                    
    console.error('error opening file: ' + err);                                
  } else {                                                                      
    fs.read(fd, new Buffer(4), 0, 4, 2, function(err, bytesRead, data){        
      if (err) throw err;                                                       
      console.log('outer data', data);                                          

      fs.read(fd, new Buffer(3), 0, 3, 0, function(err, bytesRead, data2){   
        if (err) throw err;                                                     
        console.log('inner data', data2);                                       
        fs.close(fd);                                                           

        // more code to execute after both reads                                
      });                                                                       
    });                                                                         
  }                                                                             
});   
于 2012-12-24T04:49:00.957 に答える