6

ファイルパラメータを読み取ろうとしています。このコードを作成すると:

  var fs = require('fs'),
    size = new Object();
fs.stat(file, function(err,stats){
         if(!err){
            size=stats;
         }
      })
   console.log(size);

関数を使用しようとすると、問題ありません。

 var fs = require('fs'),
    size = new Object();
function writeinfile(file){
   fs.stat(file, function(err,stats){
         if(!err){
            size=stats;
         }
      })
   console.log(size.size);  
}
writeinfile('error.log');

うまくいきません。バリアント 2 の動作を手伝ってもらえますか?

4

4 に答える 4

12

console.logはfs.statコールバックの外にあります。修正:

 var fs = require('fs'),
    size = new Object();
function writeinfile(file){
   fs.stat(file, function(err,stats){
         if(!err){
            size=stats;
            console.log(size.size);  
         }
      })

}
writeinfile('error.log');

また、Node.jsでより慣用的な(より一般的な)構文を使用するようにコードを書き直しました。

var fs = require('fs');

function writeinfile (file, cb) {
  fs.stat(file, function(err,stats){
    if(err) return cb(err);
    cb(null, stats.size); 
  })
}

writeinfile('error.log', function(err, size) {
  if(err) {
    console.log(err);
    return;
  }
  console.log('The size of the file is ' + size);
});

Hermanが彼の回答で述べたように、ファイルに書き込んでいない場合は、より適切な関数名を選択することをお勧めします。

最後に、Javascriptでは{}、のショートカットとして使用できますnew Object()。例えば:var size = {};

于 2012-10-29T19:46:14.943 に答える
1

console.log(size.size); を置く必要があります。コールバック関数内ですが、もっと説明する必要があると思います。

非同期呼び出しと Node.js イベント ループについて学ぶ必要があります。Node.js は、CPU 集約型よりも IO 集約型 (Web サーバーなど) の問題に対してスレッドを作成するより良い方法でリソースを並列化するために作成されました。複数のスレッドを作成してブロック関数を呼び出して IO を使用するよりも、IO を使用する非ブロッキング呼び出しを使用するロジックの単一スレッドの方が優れているという考え方です。

別の言語でプログラミングする場合は、アルゴリズムの同期バージョンに精通している必要があります。

var fs = require('fs'),
size = new Object();
function writeinfile(file) {
    var stats = fs.statSync(path);
    size = stats.size;
    console.log(size);
};

writeinfile('error.log');

これは Node.js コードですが、これは Node のやり方ではありません。statSync() を呼び出すと、スクリプト ブロックはディスクからの統計情報の読み取りを待機します。

ただし、 just を使用するとfs.stat()、プログラムはコードの最後まで実行され、ディスクが読み取られます。次のすべての行は、プログラムがイベント ループを達成する前に実行されます。stat の準備が整い、プログラムが最後まで実行されると、イベント ループは call の引数で渡されたコールバック関数をfs.stat(callback)呼び出します。

したがって、コードでは、stat (非同期バージョン) を呼び出し、まだ準備ができていない値を使用してみます。これは、非同期呼び出しの後のコードは常にコールバックが呼び出される前に実行されるためです。

最初のバージョンは、インタープリターでコードを手動で入力する必要があるという理由だけで機能すると思います。そのため、次の行を入力するのに必要な時間は、プログラムがイベントループを達成するのに十分です。このモードでは、コマンドを入力して Enter キーを押し、そのコードが実行されるたびに (つまり、リターンを取得するたびに)、イベント ループ内のイベントが後で呼び出されます。

于 2015-02-27T19:14:34.103 に答える
1

あなたの例では、fs.stat() の非同期性のために、console.log(size) の実行時に size の値が設定されると期待するのは正しくありません。

実際に起こることを順番に示します。

  1. モジュールを要求しfs、新しいsizeオブジェクトをインスタンス化します。
  2. コールバックで fs.stat(path,cb) を呼び出します
  3. console.log(size) を呼び出します
  4. 次に、将来のある時点で、 fs.stat() がコールバックを呼び出します

ファイル io の非同期性により、必要なファイル システム コールを実行するのにかかる時間を事前に予測できないため、この順序で処理が行われます。ディスクの現在の動作に応じて、4 ~ 4000 ミリ秒、またはそれ以上かかる場合があります。

これが、コールバックが適用された関数が完了したとき、またはこの場合はファイルパスのステータスが決定されたときに発生することが保証されているため、コールバックに依存する理由です。

そして、気を悪くしないでください。これは、非同期でプログラミングするときに誰もが犯す 1 つの間違いであり、ノードをプログラミングするときに頭を悩ませるのが最も難しい概念です。

于 2012-10-29T19:51:59.300 に答える
0

コードにはいくつかの観察事項があります。しかし、私たちは学ぶためにここにいます:

  1. 関数がそのタスクを実行した後、必要な情報を取得できるように、 をconsole.logコールバック内 (つまり のすぐ下) に配置してください。size=stats

  2. 上に次の行を追加しますif (!err)

    if (エラー) console.log(エラー);

以下が表示されます

{ [Error: ENOENT, stat 'error.log'] errno: 34, code: 'ENOENT', path: 'error.log' }

これは、パス上のエラーを意味します。簡単な修正: fs.exists()を使用してファイルが存在するかどうかを確認するか、ファイル名の前に__dirname.

  1. 最後の行は について説明してwriteinfilefs.statsますが、ファイルに関する情報を提供しています...このタスクにはfs.write()を使用することをお勧めします。
于 2012-10-29T19:43:43.920 に答える