我尝试制作读取文件参数。当我创建这段代码时:
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吗?
答案 0 :(得分: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);
});
赫尔曼在回答中提到,如果你不写文件,最好选择一个更好的功能名称。
最后,在Javascript中,您可以使用{}
作为new Object()
的快捷方式。例如:var size = {};
答案 1 :(得分:1)
在您的示例中,由于fs.stat()的异步特性,在console.log(size)运行时期望设置size的值是不正确的。
以下是实际发生的事情:
fs
模块并实例化一个新的size
对象。 事情按此顺序发生,因为由于文件io的异步性质,无法事先预测进行所需文件系统调用所花费的时间。根据光盘当前的工作情况,可能需要4到4000毫秒或更长时间。
这就是我们依赖回调的原因,因为它们可以保证在应用它们的函数完成时发生,或者在这种情况下,当确定了文件路径的状态时。
请不要感到难过。这是每个人在异步编程时犯的一个错误,在编程节点时,最难以概括为什么。
答案 2 :(得分:1)
你需要把console.log(size.size);在回调函数中,但我认为我需要更好地解释。
您需要了解异步调用和Node.js事件循环。创建Node.js是为了以更好的方式对资源进行并行处理,为更密集的IO(如Web服务器)而不是CPU强化的问题创建线程。我们的想法是,使用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()时,您的脚本阻止等待从磁盘读取统计信息。
但是,当你只使用fs.stat()
时,你的程序将一直运行到代码结束,而磁盘正在读取。所有下一行将在程序实现事件循环之前运行。当stat准备好并且程序运行到结束时,事件循环将调用您在fs.stat(callback)
调用中通过参数传递的回调函数。
因此,在您的代码中,您调用一个stat(同步版本),并尝试使用尚未准备好的值,因为异步调用之后的代码将始终在调用回调之前运行。
我认为第一个版本只是因为您应该在解释器中手动设置代码,因此,您需要键入下一行的时间才能实现事件循环。在这种模式下,每次键入命令时,按Enter键并运行该代码,即返回,事件循环中的事件将在之后调用。
答案 3 :(得分:0)
您的代码有几个观察结果。但我们在这里学习:
确保将console.log
置于回调内(即size=stats
下方),这样您就可以在函数完成任务后获得所需的信息。
在if (!err)
上方添加以下行:
if(err)console.log(err);
您将看到以下内容
{ [Error: ENOENT, stat 'error.log'] errno: 34, code: 'ENOENT', path: 'error.log' }
这意味着路径上的错误。轻松修复:使用fs.exists()检查文件是否存在,和/或始终确保文件名前加__dirname
。
writeinfile
,但fs.stats
为您提供有关该文件的信息......我建议此任务的更好功能为fs.write()。