nodejs学习笔记2

来源:互联网 发布:win10多核优化怎么开 编辑:程序博客网 时间:2024/05/29 16:45

路径操作

文件描述符句柄在node中是一个整数,其中1,2,3分别表示标准输入文件,标准输出文件,标准错误文件的描述符。

规范化路径:

path.normalize('/foo/bar//baz/asdf/quux/..')///foo/bar/baz/asdf

连接路径:

path.join('/foo','bar','baz/asdf','quux','..')//'/foo/bar/baz/asdf';

解析路径:

path.resolve('/foo/bar','./baz');//'/foo/bar/baz'path.resolve('/foo/bar','/tmp/file/');//'/tmp/file'

如果解析的结果不是绝对路径,那么path.resolve函数会将当前工作目录附加到解析结果的前面。
获取文件路径的目录部分:

path.dirname('/foo/bar/quux.txt');//'/foo/bar'

从文件路径中提取文件名:

path.basename('/foo/bar/quux.html');//'quux.html'path.basename('/foo/bar/quux.html','.html');//'quux'path.extname('/foo/bar/quux.html');//'.html'

判断目录是否存在:

//该方法是path唯一与文件系统交互的path.exists('/etc/passwd',function(exists){    console.log('exists:',exists);//true});

node 0.8用fs.exists函数代替了path.exists函数。

fs模块

查询文件的统计信息(大小,创建时间等):

fs.stat('/etc/passwd',function(err,stats){    if(err){throw err;}    console.log(stats);//输出文件的元信息    stats.isFile();//如果是标准文件返回true    stats.isDirectory();//是目录返回true    stats.isBlockDevice();//块设备返回true    stats.isCharacterDevice();//字符设备    stats.isSymbolicLink();//符号链接    stats.isFifo();//FIFO    stats.isSocket();//套接字});

打开文件并读取文件:

fs.open('/path/to/file','r',function(err,fd){    //文件描述符fd    if(err){throw err;}    var readBuffer = new Buffer(1024),        bufferOffset = 0,        bufferLength = readBuffer.length,        filePosition = 100;    fs.read(fd,readBuffer,bufferOffset,bufferLength,filePosition,        function read(err,readBytes){        if(err) {throw err;}        console.log('just read'+readBytes+'bytes');        if(readBytes>0)//如果等于0则代表到达文件结尾        console.log(readBuffer.slice(0,readBytes));    });});

写入文件:

fs.open('./myfile.txt','a',function open(err,fd){    if(err){throw err;}    var writeBuffer = new Buffer("writing this string"),        bufferPosition=0,        bufferLength=writeBuffer.length,filePostion=null;    fs.write(fd,writeBuffer,bufferPosition,bufferLength,        filePosition//为null代表从当前文件的游标开始写入        function wrote(err,written){            console.log('wrote'+written+'bytes');        });});

关闭文件只需调用fs.close(fd,[,callback])。

进程

执行外部命令

当需要执行一个外部shell或者可执行文件时,可以使用child_process模块。

var child_process = requier('child_process');var exec = child_process.exec;exec(command,function(err,stdout,stderr){...});//command为命令字符串

还可以再回调函数之前传入一个包含配置选项的可选参数。

var options = {    timeout:1000,//命令执行的超时时间    maxbuffer:1024,//stdout流和stderr流的最大容量,如果超过则子进程终止    killSignal:'SIGKILL',//如果超时或超过输出缓存容量,该信号就会被发送到子进程。    env:null;//传递给子进程的环境变量。默认为null.}

父进程环境变量扩展:

var env = process.env,    varName,    envCopy={};for(varName in env){    envCopy[varName] = env[varName];}//自定义变量envCopy['custom1'] = 'some value';...

生成子进程

使用exec()函数启动外部进程有如下缺点:
1. 除了命令行参数和环境变量之外,不允许与子进程通信。
2. 子进程的输出是被缓存的,无法对其流操作,可能会耗尽内存。
但是node会在父子进程之间创建一个双向通信通道,利用此通道发送字符串形式的数据或者强制终止子进程。

//使用child_process.spawn函数创建子进程var spawn = require('child_process').spawn;var child = spawn('tail',['-f','/var/log/system.log']);//监听子进程的输出数据child.stdout.on('data',function(data){...});child.stderr.on('data',function(data){...});

向子进程发送数据

父进程想子进程的标准输入流中写入数据(childProcess.stdin)
子进程也可用process.stdin流来监听数据。但是先恢复流,因为默认情况下它属于暂停状态。
子进程child.js:

process.stdin.resume();process.stdin.on('data',function(data){    var number = parseInt(data.toString(),10);    number+=1;    process.stdout.write(number+"\n");});

父进程:

var child = spawn('node',['child.js']);setInterval(function(){    var number = Math.floor(Math.random()*1000);    child.stdin.write(number+"\n");    child.stdout.once('data',function(data){        console.log(data);    });});

监听子进程的退出:

child.on('exit',function(code){    console.log('child process terminated with code'+code);});

发送信号终止进程

如果进程收到一个不知如何处理的信号,它就会终止。一些信号可以由子进程处理,一些信号只能由操作系统处理(例如SIGKILL,SIGSTOP)。可以使用child.kill()发送信号,默认是SIGTERM,也可传入信号参数。

var child = spawn('sleep',['10']);setTimeout(function(){    child.kill();},1000);

可以重写信号的默认行为:

child.kill('SIGUSR2');//子进程process.on('SIGUSR2',function(){console.log('got a sigusr2 signal';)});

创建文件系统流

var rs = fs.createReadStream('/path/file');

可以向此方法传递第二个参数options,包含几下选项:
encoding:data事件发送的字符串的编码格式
fd:如果已经有了一个打开文件描述符,则可传入。默认null.
bufferSize:要被读取的每个文件块的大小,默认64KB。
start:文件中第一个被读取的字节位置。
end:文件中最后一个被读取的字节位置。

创建一个文件可写流:

var rs = fs.createWriteStream('/path/to/file',options);//options默认值如下:{    flags:'w',//标志位    encoding:null,    mode:0666   //权限}

避免慢客户端问题

大多数情况下,可以通过暂停数据生产者来避免填满具有未刷新缓冲区的内存(可读流)以便让消费者的数据(可写流)不会被传入核缓冲区。

require('http').createServer(function(req,res){    var rs = fs.createReadStream('/path/file');    rs.on('data',function(data){        if(!res.write(data)){            rs.pause();        }    });    res.on('drain',function(){        rs.resume();    });    rs.on('end',function(){        res.end();    });}).listen(8080);

stream.pipe()

stream.pipe()方法实现了以上过程。由传输源调用,接收目标可写流作为第一个参数。

require('http').createServer(function(req,res){    var rs = fs.createReadStream('/path/file');    rs.pipe(res);}).listen(8080);

默认情况下end()会在可读流结束时在可写流上调用。可以传入end:false自定义该行为。

rs.pipe(res);rs.on('end',function(){    res.write('that is all');    res.end();})
0 0