本文的代码和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 当前执行脚本的所在目录