Node.js开发指南之二:核心模块介绍

本文的代码和API说明基于Node 0.8.12版本,并不能保证在不同的node版本顺利执行

1 stdio

console模块是Node提供的核心模块,提供基本的输出功能。

console.log([format],...) 向控制台输出日志,类似的API还有info() err() warn(),格式有%s,%d,%j(json格式)

console.dir(object)       利用util.inspect()输出对象的分析

console.time(tag) 

console.timeEnd(tag)  配合time() 生成一个测时器,并输出其间隔的时间

console.assert(expr,msg)  若expr为假,则输出msg

console.trace(tag)            输出当前的栈信息

//演示代码
//log err warn info have the same usage
console.log('%s,%d,%j','hello world',1000,{name:'Bill Gate',Sexy:'Male',age:18,product:['xp','win7','win8']});

//test dir
var Person = function(name,age)
{
  this.name=name;
  this.age=age;
};

var p = new Person('Jobs',23);

console.dir(p);
console.dir(Person);

//test time
console.time('timer1');
for(var i=0;i<10000000;i++)
{
    if(i%2==0)
    {

    }
}
console.timeEnd('timer1');

try
{
  console.assert(1==22,'if equal are wrong');
}
catch(err)
{
  console.log('%s,%s',err.name,err.message);
}

console.trace('trace');

//输出如下
hello world,1000,{"name":"Bill Gate","Sexy":"Male","age":18,"product":["xp","win7","win8"]}
{ name: 'Jobs', age: 23 }
[Function]
timer1: 169ms
AssertionError,if equal are wrong
Trace: trace
    at Object.<anonymous> (/home/aaaa/nodejs/stdio.js:36:9)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

2 URL与QueryString

这两个模块是Node提供的核心模块,用于处理URL及URL中的查询串。通常情况下,不需要直接处理querystring,因为url模块的支持。

url.parse(url,qs,sl)  将url解析为一个对象,其中包含host,hostname,port等字段,若qs为true,则调用querystring解析查询串

url.format(obj)        将obj生成为一个url字符串

querystring.stringify(obj,'sep','eq')  将对象obj生成查询串
querystring.parse(str) 解析查询串为对象

//url test
var url = require('url');
var qs = 'http://user:[email protected]:8080/p/a/t/h?query=string#hash';

var obj = url.parse(qs,true,true);
console.log(obj);

var dst = {protocol:'http',host:'localhost',pathname:'/index.php',search:'?cmd=version'};
console.log(url.format(dst));

var diff = url.resolve('http://localhost/index.php?cmd=version','http://localhost/index.php');
console.log(diff);

//querystring test
var querystring = require('querystring');
var qstr = querystring.stringify({cmd:'get',name:'bill',sexy:'mail'});
console.log(qstr);

console.log(querystring.parse(qstr));


//输出
{ protocol: 'http:',
  slashes: true,
  auth: 'user:pass',
  host: 'host.com:8080',
  port: '8080',
  hostname: 'host.com',
  href: 'http://user:[email protected]:8080/p/a/t/h?query=string#hash',
  hash: '#hash',
  search: '?query=string',
  query: { query: 'string' },
  pathname: '/p/a/t/h',
  path: '/p/a/t/h?query=string' }
http://localhost/index.php?cmd=version
http://localhost/index.php
cmd=get&name=bill&sexy=mail
{ cmd: 'get', name: 'bill', sexy: 'mail' }


3  Path与File System

Path模块则提供了对路径名称的一些便捷操作,其将输入串作为路径栈来处理,与物理文件系统无关。

path.normalize('path')   处理path中的' . '与'..'

path.join(a,b,..z)  处理为a/b/.../z,并对结果执行normalize

path.resolve(a,b,...z) 对每个元素执行cd item,返回最终结果

path.relative(a,b)  返回b对于a的切换方式,可包含'.'与'..'

path.dirname(path) path.basename(path,'mask') 返回路径的目录部分与文件名部分

path.extname(path) 返回路径的扩展名部分

path.seq  OS特定的路径分隔符 "\\" 或  "/"

console.log(path.normalize('~/workspace/linda/../help'));
console.log(path.join('hello','world','..'));
console.log(path.resolve('/home/aaa','workspace','..'));
console.log(path.relative('/home/aaa','/home/bbb'));
console.log(path.basename('/home/aaa/1.txt','.txt'));
console.log(path.dirname('/home/aaa/1.txt'));

//输出
~/workspace/help
hello
/home/aaa
../bbb
1
/home/aaa


File System提供了对文件与目录的创建、删除、权限设置,并以及文件的打开、读写与关闭。文件API提供两套接口,分别支持同步与异步调用。区别是,同步情况异常会立即抛出,需要用try-catch捕获,而在异步情况下,异常会传递给回调函数处理。值得注意的是异步情况下,不同的事件的完成顺序是未决的,因而对于有顺序的操作,最好在函数的事件链中去完成。由于同步操作与POSIX同名调用类似,因此这里只介绍异步接口。

fs.rename(oldPath, newPath, [callback])   修改名字,回调函数为function(exception) {}

fs.truncate(fd, len, [callback])  截断文件

fs.chown(path, uid, gid, [callback])  fs.fchown(fd, uid, gid, [callback])  修改文件所属

fs.chmod(path, mode, [callback]) fs.fchmod(fd, mode, [callback]) 修改文件权限

fs.stat(path, [callback])   fs.lstat(path, [callback])  fs.fstat(fd, [callback])  返回文件stat,回调为function(err,state) {}

fs.link(srcpath, dstpath, [callback])  fs.symlink(srcpath, dstpath, [type], [callback]) 创建链接与符号链接

fs.readlink(path, [callback])  读取link的内容

fs.unlink(path, [callback])

fs.rmdir(path, [callback])   fs.mkdir(path, [mode], [callback])  目录创建与删除

fs.readdir(path, [callback])  读取目录内容  回调为function(err,files) {}

fs.open(path, flags, [mode], [callback])    回调为function(err,fd) {}

fs.write(fd, buffer, offset, length, position, [callback])  回调为function(err,len,buf) ;

fs.read(fd, buffer, offset, length, position, [callback])  回调为function(err,len,buf) ;

fs.close(fd, [callback])

fs.utimes(path, atime, mtime, [callback])  fs.futimes(fd, atime, mtime, [callback])  修改文件的访问时间与修改时间

fs.fsync(fd, [callback]) 

fs.readFile(filename, [encoding], [callback])     高层接口,回调为function(err,data)

fs.writeFile(filename, data, [encoding], [callback])  高层接口,回调为function(err)

fs.appendFile(filename, data, encoding='utf8', [callback])

fs.createReadStream(path,[opt]) 

fs.createWriteStream(path,[opt]) 从路径创建输入与输出流

 4 Stream

Stream是Node实现的一种面向流处理的接口,支持文件流、HTTP数据流、标准IO流等进行抽象操作。

Stream分为readStream与writeStream两种类型

read stream 定义了下列事件 data,end,error,close 用于在底层处理流的过程中回调用户的事件监听器。

setEncoding('charset')  设置流的字符编辑,默认为utf-8

pause() resume() 暂停与恢复流处理,需要注意的是有些底层处理并不能立即生效,在pause后一段时间内仍会抛出data事件

destroy() 在流处理结束后,释放流使得底层可以关闭文件

pipe(dstream,[opt]) 将输入流复制到目标输出流

writable Stream定义了下列事件: drain,error,close,pipe 用于底层在处理流的过程中回调用户的事件监听器

write(string,[charset])  

write(buff) 写入输出流

end()  

end(string,encoding) end(buf) 定稿输出流并写入EOF

destory()/destroySoon()  关闭底层资源,后者后将写入缓存区写空后释放。

//基于fs接口的stream代码显示
var fs = require('fs');

rdstream = fs.createReadStream('/etc/passwd');
wtstream = fs.createWriteStream('/tmp/pasd');

rdstream.setEncoding('utf-8');
rdstream.pipe(wtstream);

rdstream.on('data',function(data){
  //console.log(data);
});

rdstream.on('end',function(){
  console.log('File read End');

  rdstream.destroy();
  wtstream.end();
  console.log('write EOF to File');
  wtstream.destroy();

});

rdstream.on('error',function(err){
  console.log(err);
  rdstream.destroy();

});

rdstream.on('close',function(){
  console.log('Read File closed');
});

wtstream.on('error',function(err){
  console.log(err);
});

wtstream.on('drain',function(){
  console.log('write buf empty');
});

wtstream.on('pipe',function(){
  console.log('piped from input');
});

wtstream.on('close',function(){
  console.log('Write file closed');
});

5 定时器

定时器操作被导出到全局命名空间中,不需要单独包含

setTimeout(callback, delay, [arg...])   设置超时执行
clearTimeout(timeoutId)   
setInterval(callback, delay, [arg...])    设置间隔执行
clearInterval(intervalId)

6 http

 本模块较大,在下篇文章中说明。

 

7 child process

    此模块提供了操作子进程以及与进程间通信的基本功能。这个模块提供执行子进程的四种方式,并返回子进程的抽象,ChildProcess类型的实例。子进程类型其实是一个事件发生器,其上定义了子进程生命周期中的各种事件,如exit, close, message,disconnect事件。实例可以取到对应进程的相关属性如标准输入、输出、错误、进程ID,此外还提供了对进程发送消息的接口send,kill()和disconnect()。

7.1 创建进程

spawn(cmd, [args,...], [opt])  基于cmd命令执行一个子进程,命令的参数为args,若无则为空数据。option={cwd, stdio, customFds, env, detatched}

exec(cmd,[opt],callback )    基于cmd命令执行子进程,命令参数为空格分隔。回调的原型为function(err,stdout, stderr) {}。option={cwd, stdio, customFds, env,encoding,timeout,maxBuffer,killSignal}

execfile(file , [args,...], [opt],callback)  对于非shell命令的程序,可以通过execfile来执行,回调函数原型为function(err,stdout, stderr) {}。option={cwd, stdio, customFds, env,encoding,timeout,maxBuffer,killSignal}

fork(module, [args,...],[opt])  在子进程中执行一个node模块。option={cwn,env,encoding}.

7.2 选项说明

cwd:当前工作区

env 进程执行环境

stdio: 一个数组,数组每个位置对应子进程的一个文件fd,每个位置的值可能为pipe, ipc,ignore,stream obj, null, 正数。pipe表示创建一个父子间的管道,父进程可以通过child_process.stdio[fd]来获取写入端。IPC,创建一个IPC信道。可以使用send()来向此文件fd进行消息的传递,并在接受方引发on('message')事件。 ignore:忽略IO,重定向到/dev/null。Stream obj :在进程间共享一个re/wt 流对象,以操作子进程的TTY,FILE,PIPE,SOCKET等。正整数:其值表示在父进程中打开的文件fd,共享给子进程。null,使用默认值。0,1,2为pipe,>3的为ignore。为了方便书写, node定义了三个数组,'ignore','pipe','inherit',分别表示对于0-2的文件进行相应的操作

例如,如果想让子进程直接使用父进程的输出,可以require('child_process').spawn('ls',[ ],{stdio:‘inherit’});

detached:让子进程成为新进程组的首进程,从而在父进程退出后仍可继续执行。默认情况下父进程会等子detached进程的结束,可以通过child.unref()来避免这种等待。尽管如此,若希望子进程正常执行,仍需要将子进程与父进程的控制终端相剥离。

timeout: 若>0,则在执行超时后由选项指定的信号终止。

killSignal:指定期望接收的终止信号

maxBuffer:指定标准输出和错误的最大数据量,超出后子进程被kill

7.3 ChildProcess对象

本类是子进程的抽象对象,支持以下操作和属性

kill(signal)   使用信号终止进程

send(msg, [sendHandler])  这里需要注意的是,在父进程中调用send()的事件会被子进程注册的事件处理函数处理,而在子进程中给自己send()会触发在父进程中注册的事件处理函数。
disconnect()

stdin,stdout,stderr,  Readable Stream或Writable Stream

pid:子进程的PID

子进程在执行过程中会触发以下事件:

exit:进程终止时触发。回调function(code,signal) ,若进程正常结束,则code为执行 进程的退出码,否则为null。若进程由信号终止,则signal为收到的信号。

close:进程的 stdio流结合时触发

disconnect:调用dieconnect()后触发,调用后不可以再向子进程发送消息,可以检查child.connected属性

message:在调用send()后触发,function(msg,sendHandler){}    sH可能为socket对象,或server对象。

//类似在shell下执行ps ax|grep "ssh"
var spawn = require('child_process').spawn,
    ps    = spawn('ps', ['ax']),
    grep  = spawn('grep', ['ssh']);

ps.stdout.on('data', function (data) {
  grep.stdin.write(data);
});

/*
ps.stderr.on('data', function (data) {
  console.log('ps stderr: ' + data);
});
*/

ps.on('exit', function (code) {
  if (code !== 0) {
    console.log('ps process exited with code ' + code);
  }
  grep.stdin.end();
});

grep.stdout.on('data', function (data) {
  console.log('' + data);
});

/*
grep.stderr.on('data', function (data) {
  console.log('grep stderr: ' + data);
});

grep.on('exit', function (code) {
  if (code !== 0) {
    console.log('grep process exited with code ' + code);
  }
});
*/


 

 

8 global
全局空间可以访问console,process,buffer,timer模块,不需要require

console与timer在上面已有说明,process提供了node执行进程的运行环境、参数、进程的gid,uid,运行时间等等,具体可以查找process模块

__filename 当前执行脚本的文件名

__dirname  当前执行脚本的所在目录

 

 

 

你可能感兴趣的:(Node.js开发指南之二:核心模块介绍)