在nodejs中使用fs.stat的问题

我试图使读取文件参数。 当我做这个代码时:

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

没关系,当我尝试使用function:

  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的工作吗?

你的console.log在你的fs.statcallback之外。 修复:

  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); }); 

正如赫尔曼在他的回答中所提到的,如果不写入文件,select一个更好的函数名是个好主意。

最后,在Javascript中,可以使用{}作为new Object()的快捷方式。 例如: var size = {};

在你的例子中,由于fs.stat()的asynchronous性质,当console.log(size)运行时,期望size的值被设置是不正确的。

以下是实际发生的情况:

  1. 您需要使用fs模块并实例化新的size对象。
  2. 你用callback调用fs.stat(path,cb)
  3. 你调用console.log(size)
  4. 那么在将来的某个时候 ,fs.stat()会调用你的callback函数

由于文件io的asynchronous特性,事先无法预测进行所需的文件系统调用所花费的时间,因此事情按此顺序发生。 取决于光盘目前在做什么,可能需要4到4000毫秒,或更多。

这就是为什么我们依赖callback函数,因为它们保证在应用函数完成时发生,或者在这种情况下确定文件path的状态。

请不要感觉不好。 这是每个人在asynchronous编程时犯的一个错误,在编程节点时,这是最难缠的概念。

你需要把console.log(size.size); 里面的callback函数,但我想我需要解释更好。

您需要了解asynchronous调用和Node.js事件循环。 创buildNode.js的目的是为了更好地为资源进行paralelize,为CPU密集度更高的IO密集型问题(如networking服务器)创build线程。 这个想法是,一个单线程的非阻塞调用使用IO的逻辑比创buildmultithreading和调用块函数来使用IO好。

如果你用另一种语言编程,你应该熟悉你的algorithm的同步版本:

 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()时,您的脚本块将等待从磁盘读取统计信息。

但是,当你只使用fs.stat() ,你的程序将运行直到代码结束,而磁盘正在读取。 所有下一行将在程序实现事件循环之前运行。 只要统计准备就绪,程序运行到结束,事件循环将调用您在fs.stat(callback)调用中通过parameter passing的callback函数。

因此,在你的代码中,你调用了一个stat(assynchronous版本),并尝试使用一个尚未准备好的值,因为在调用callback之前总是会执行assynchronous调用之后的代码。

我认为第一个版本只是因为你应该在解释器中手动打破代码,所以,你需要input下一行的时间足以让程序实现事件循环。 在这种模式下,每input一个命令,按回车键,那个代码就运行了,也就是说,你得到一个返回,事件循环中的事件将被调用。

有几个观察你的代码。 但我们在这里学习:

  1. 确保把console.log放在callback里面(也就是在size=stats下面),这样你就可以在函数完成任务后得到你需要的信息。

  2. if (!err)

    如果(err)console.log(err);

你会看到以下内容

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

这意味着path上的错误。 易于修复:使用fs.exists()来检查文件是否存在,和/或者,总是确保以__dirname为前缀。

  1. 最后一行是关于writeinfile ,但是fs.stats会给你提供关于这个文件的信息……我build议一个更好的函数是fs.write()来完成这个任务。