1 // 在node的应用程序中,执行异步操作的函数将回掉函数最为最后一个参数,回掉函数接收错误对象作为第一个参数 2 var fs = require('fs') 3 fs.readFile('input.txt',function (err,data) {//这个是异步函数,用于读取文件; 4 if(err){ 5 console.log(err.stack) 6 return 7 } 8 console.log(data.toString()) 9 }) 10 console.log('程序执行完毕') 11 12 // 执行结果: 13 // 程序执行完毕 14 // 菜鸟教程官网地址:www.runoob.com
二:
1 // EventEmitter 2 node.js中所有异步操作,在完成时都会发送一个事件到事件队列; 3 node.js里面有很多对象都会分发事件:一个net.server对象会在每次有新连接时触发一个事件。一个fs.readStream对象会在文件被打开的时候触发一个事件;所有这些产生事件 4 // 的对象都是events.EventEmitter的实例 5 events模块只提供了一个对象;events.EventEmitter.EventEmitter的核心就是事件触发与事件监听功能的封装; 6 var EventEmitter = require('events').EventEmitter; 7 var event = new EventEmitter(); 8 event.on('some_event',function () { 9 console.log('some_event事件触发') 10 }) 11 setTimeout(function(){ 12 event.emit('some_event') 13 },2000) 14 15 原理分析:event对象注册了事件some_event的一个监听器,通过setTimeout在2s后向event对象发送some_event,此时会调用some_event监听器 16 17 对于每个事件,EventEmitter支持若干个事件监听器;当事件触发时,注册到这个事件的事件监听器被一次调用,事件参数作为回调函数参数传递 18 19 var events = require('events') 20 var emitter = new events.EventEmitter(); 21 emitter.on('someEvent',function(arg1,arg2){ 22 console.log('listener1',arg1,arg2) 23 }) 24 emitter.on('someEvent',function(arg1,arg2){ 25 console.log('listener2',arg1,arg2) 26 }) 27 emitter.emit('someEvent','arg1参数','arg2参数') 28 29 运行结果: 30 $ node event.js 31 listener1 arg1 参数 arg2 参数 32 listener2 arg1 参数 arg2 参数 33 分析:emitter为事件someEvent注册了两个事件监听器,然后触发了someEvent事件; 34 35 emiter的方法: 36 addListener(event,listener)为指定事件添加一个监听器到监听器数组的尾部; 37 on(event,listener)为指定事件注册一个监听器,接受一个字符串event和一个回掉函数 38 onece(event,listener)为指定事件注册一个单次监听器, 39 removeListener(event,listener)移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器 40 removeAllLissteners([event])移除所有事件的所有监听器,如果指定事件,则移除指定事件的所有监听器; 41 setMaxListeners(n)默认情况下,EventEmitters如果你添加的监听器超过10个就会是输出警告信息,setMaxListeners用于提高监听器默认限制的数量 42 listeners(event)返回指定始事件的监听器数组 43 emit(event,[arg1],[arg2],[...])按参数的顺序执行每个监听器; 44 事件: 45 // newListener该事件在添加新的监听器时触发; 46 // removeListener在移除监听器的时候触发; 47 48 实例: 49 var events = require('events') 50 var eventEmitter = new events.EventEmitter(); 51 var listener1 = function listener1() { 52 console.log('监听器listener1执行') 53 } 54 var listener2 = function listener1() { 55 console.log('监听器listener2执行') 56 } 57 // 绑定 connection 事件,处理函数为 listener1 /2 58 eventEmitter.addListener('connection',listener1) 59 eventEmitter.addListener('connection',listener2) 60 61 var eventListeners = eventEmitter.listenerCount('connection') 62 console.log(eventListeners+'个监听器监听连接事件') 63 eventEmitter.emit('connection') 64 65 eventEmitter.removeListener('connection',listener1) 66 console.log('listener1不再受监听') 67 68 eventEmitter.emit('connection') 69 70 eventListeners = eventEmitter.listenerCount('connection') 71 console.log(eventListeners+ "个监听器") 72 console.log('程序执行完毕') 73 error事件
1 // Buffer(缓冲区) 2 // Buffer类专门用来存放二进制数据的缓存区 3 // Buffer实例一般用于标识编码字符的序列,,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。 4 var buf = Buffer.from ('bobobo','ascii') 5 console.log(buf.toString('hex')) 6 console.log(buf.toString('base64'))
1 Stream(流) 2 Stream是一个抽象接口,node中有很多对象实现了这个接口,例如,对http服务器发起请求的request对象就是一个Stream; 3 Stream有四种流类型: 4 Readable- -- 可读操作 5 Writable 可写操作 6 Duplex可读可写 7 Transform操作被写入输入,然后读出结果; 8 所有的Stream对象都是EventEmitter的实例,常用的事件有: 9 data 当数据可读时触发 10 end没有更多数据可读时触发 11 error在接收和写入过程中发生错误时候触发 12 finish所有数据已被写如底层系统时候触发; 13 14 实例:从流中读取数据 15 var fs= require ('fs') 16 var data ='' 17 // 创建可读流 18 var readerStream = fs.createReadStream('input.txt') 19 // 设置编码 20 readerStream.setEncoding('UTF8') 21 // 处理流事件 data end error 22 readerStream.on('data',function(chunk){ 23 data += chunk; 24 }) 25 readerStream.on('end',function () { 26 console.log(data) 27 }) 28 readerStream.on('error',function (err) { 29 console.log(err.stack) 30 }) 31 console.log('程序执行完毕') 32 实例:写入流 33 var fs = require('fs') 34 var data = '我是邓艳波' 35 //创建一个可以写入的流,写入到文件input.txt中 36 var writeStream = fs.createWriteStream('input.txt'); 37 //设置编码 38 writeStream.write(data,'UTF8') 39 //标记文件末尾 40 writeStream.end() 41 //处理流事件 --data ,end,error 42 writeStream.on('finish',function () { 43 console.log('写入完成') 44 }) 45 writeStream.on('error',function (err) { 46 console.log(err) 47 }) 48 console.log('程序执行完毕') 49 50 管道流:提供了一个输出流到输入流的机制,通常我们用于从一个流中获取数据并将数据传递到另一个流中; 51 var fs = require('fs') 52 //创建一个可读流 53 var readerStream = fs.createReadStream('input.txt') 54 //创建一个可写流 55 var writerStream = fs.createWriteStream('output.txt') 56 //管道读写操作,将input.txt内容写到output.txt中 57 readerStream.pipe(writerStream) 58 console.log('程序执行完毕') 59 60 61 62 链式流:通过连接输出流到另外一个流并创建多个流操作链的机制;链式流一般用于管道操作 63 实例:利用管道和链式压缩和解压文件 64 var fs=require('fs') 65 var zlib= require('zlib') 66 //压缩所文件input.txt为input.txt.gz 67 fs.createReadStream('input.txt') 68 .pipe(zlib.createGzip()) 69 .pipe(fs.createWriteStream('input.txt.gz')) 70 console.log('文件压缩完成') 71 72 73 解压文件: 74 var fs = require('fs') 75 var zlib = require('zlib') 76 fs.createReadStream('input.txt.gz') 77 .pipe(zlib.createGunzip()) 78 .pipe(fs.createWriteStream('input.txt')) 79 console.log('文件解压完成')
1 // node.js的模块系统 2 // 作用:方便node.js的文件可以相互调用;一个node.js文件就是一个模块; 3 // 创建模块: 4 // var world = require('./world'); 5 // world.world() 6 7 // world.js文件内容: 8 // // exports.world = function () { 9 // // console.log('hello bobo') 10 // // } 11 12 // 分析:world.js通过exports对象把world作为模块的访问接口,在hello.js中,引入加载这个模块,然后就可以直接访问world.js中exports对象的成员函数了; 13 // 若知识想把一个对象封装到模块中,则: 14 // module.exports = function () { 15 // 16 // } 17 // 实例: 18 19 // world.js 20 // function world(){ 21 // var name ; 22 // this.setName = function (thyName) { 23 // name = thyName 24 // }; 25 // this.setHello = function () { 26 // console.log('hello ' + name) 27 // } 28 // } 29 // module.exports = world; 30 // 31 // // hello.js 32 // var World = require('./world') 33 // world = new World(); 34 // world.setName('DengYanbo') 35 // world.setHello() 36 // 37 // 输出:hello DengYanbo
1 Node.js函数: 2 在js中,一个函数可以作为另外一个 函数的参数,我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数; 3 举例: 4 function say(word){ 5 console.log(word) 6 } 7 function execute(someFunction,value) { 8 someFunction(value) 9 } 10 execute(say,'hello') 11 分析:打印出hello 12 13 函数传递时如何让http服务器工作的: 14 var http = require('http') 15 http.createServer(function (request,response) { 16 response.writeHead(200,{'Content-Type':'text/plain'}); 17 response.write('hello world'); 18 response.end() 19 }).listen(8888)
1 // Node.js路由: 2 // 我们要为路由提供请求的URL和其他需要的GET及post参数,随后路由需要根据这些数据执行相应的代码. 3 // 因此我们需要查看HTTP请求,从中提取出请求的URL以及get/post参数. 4 // 我们需要的所有是数据都会包含在request对象中,该对象作为onRequest()回调函数的第一个参数传递,但是为了解析这些数据,我们需要额外的node.js模块,他们分别是url和querystring模块; 5 6 // server.js 7 var http = require('http') 8 var url = require('url') 9 function start(route) { 10 function onRequest(request,response) { 11 var pathname = url.parse(request.url).pathname; 12 console.log('Request for' +pathname +'received.') 13 //将路由函数作为参数传递过去 14 route(pathname) 15 response.writeHead(200,{'Content-Type':'text/plain'}); 16 response.write('hello world'); 17 response.end() 18 } 19 20 http.createServer(onRequest).listen(8888); 21 console.log('Server has started') 22 } 23 exports.start = start 24 25 26 // router.js 27 function route(pathname) { 28 console.log('About to route a request for' +pathname) 29 } 30 exports.route = route 31 // 如何将路由和服务器整合起来: 32 33 34 // index.js 35 var server = require('./hello') 36 var router = require('./router') 37 server.start(router.route)
1 Node.js的全局对象: 2 js的全局对象时window,node的全局对象是global; 3 _fileName:当前正在执行的脚本的文件名,将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同,如果在模块中,返回的是模块文件的路径 4 console.log(__filename)//C:UsersyangguoeDesktop ode Projecthello.js 5 _dirname:当前执行脚本所在的目录 6 console.log( __dirname )////C:UsersyangguoeDesktop ode Project 7 注意:是两个下划线 8 setTimeout(cb,ms)全局函数在指定的ms后执行指定函数cb; 9 function printHello() { 10 console.log('hello world') 11 } 12 setTimeout(printHello,2000) 13 clearTimeout(t)停止一个之前通过setTimeout()创建的定时器;参数t是通过setTimeout()函数创建的定时器; 14 function printHello(){ 15 console.log('hello world') 16 } 17 var t = setTimeout(printHello,200) 18 clearTimeout(t) 19 setInterval(cb,ms)//在指定的毫秒数后执行指定函数; 20 function printHello (){ 21 console.log('hello bobo') 22 } 23 setInterval(printHello,200) 24 25 console方法: 26 console.log() 27 console.info()//输出信息性消息 28 console.error()//输出错误消息 29 console.warn() 30 console.dir()用来对一个对象进行检查,并以易于阅读和打印的格式显示 31 console.time()/输出事件,表示计时开始 32 console.timeEnd()//结束时间,标识计时结束 33 34 35 process:用于描述当前Node.js进程状态的对象;提供了一个与操作系统的简单接口; 36 exit:当进程准备退出时触发; 37 beforeExit:当node清空事件循环,并且没有其他安排时触发这个事件; 38 Signal:当进程接收到信号时就触发; 39 40 process.on('exit',function (code) { 41 //以下代码永远不会执行 42 setTimeout(function () { 43 console.log('该代码不会执行') 44 },0) 45 console.log('退出码为:',code) 46 }) 47 console.log('程序执行结束') 48 49 执行结果为: 50 程序执行结束 51 退出码为: 0
1 Node.js的文件系统; 2 var fs = require('fs') 3 //异步读取 4 fs.readFile('input.txt',function (err,data) { 5 if(err){ 6 return console.error(err) 7 } 8 console.log('异步读取:'+data.toString()) 9 }) 10 11 //同步读取 12 var data = fs.readFileSync('input.txt') 13 console.log('同步读取:'+data.toString()) 14 console.log('程序执行完毕') 15 16 17 打开文件 18 fs.open(path, flags[,mode],callback) 19 path:文件路径 20 flags:文件打开的行为:如r时以读取的模式;r+:读写模式;rs:同步读方式;rs+同步方式读写 21 mode:设置文件模式(权限) 22 callback:回调函数,带有两个参数:callback(err,fd) 23 var fs = require('fs') 24 //异步打开文件 25 console.log('准备打开文件') 26 fs.open('input.txt','r+',function (err,fd) { 27 if(err){ 28 return console.error(err) 29 } 30 console.log('文件打开成功') 31 }) 32 33 34 获取文件信息:fs.stat(path,callback) 35 path:文件路径; 36 callback:回调函数,带有两个参数(err,stats),stats是fs.Stats对象 37 38 fs.stat(path)执行后,会将stats类的实例返回给其回调函数,可以通过stats类中的提供方法判断文件的相关属性.如判断是否为文件 39 var fs = require('fs') 40 fs.stat('C:/Users/yangguoe/Desktop/node Project/calc.js',function(err,stats){ 41 console.log(stats.isFile())//true 42 }) 43 stats类中的方法有: 44 stats.isFile()是否是文件 45 stats.isDirectory()是否是目录 46 stats.isBlockDevice()是否是块设备 47 stats.isCharacterDevice()是否是字符设备 48 stats.isSymbolicLink()是否是软连接 49 stats.isFIFO()是否是FIFO 50 stats.isSocket()是否是Socket 51 52 53 var fs = require('fs') 54 console.log('准备打开文件') 55 fs.stat('input.txt',function(err,stats){ 56 if(err){ 57 return console.error(err) 58 } 59 console.log(stats) 60 console.log('读取文件信息成功') 61 62 //检测文件类型 63 console.log('是否为文件(isFile)?'+ stats.isFile()) 64 console.log('是否为目录(isDirectory?' + stats.isDirectory()) 65 }) 66 67 打印结果为: 68 准备打开文件! 69 { dev: 16777220, 70 mode: 33188, 71 nlink: 1, 72 uid: 501, 73 gid: 20, 74 rdev: 0, 75 blksize: 4096, 76 ino: 40333161, 77 size: 61, 78 blocks: 8, 79 atime: Mon Sep 07 2015 17:43:55 GMT+0800 (CST), 80 mtime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST), 81 ctime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST) } 82 读取文件信息成功! 83 是否为文件(isFile) ? true 84 是否为目录(isDirectory) ? false 85 86 87 88 写入文件:fs.writeFile(file,data[,optionss],callback) 89 file:文件名/文件描述符 90 data:要写入文件的数据; 91 options:是一个对象,包含{encoding,mode,flag}默认编码为 utf8, 模式为 0666 , flag 为 'w' 92 callback:回掉函数只包含错误信息参数书,在写入失败时候返回 93 var fs = require('fs') 94 console.log('准备写入文件') 95 fs.writeFile('input.txt','我是通过fs.writeFile写入文件的内容',function (err) { 96 if(err){ 97 return console.error(err) 98 } 99 console.log('数据写入成功') 100 console.log("--------我是分割线-------------") 101 console.log("读取写入的数据!"); 102 fs.readFile('input.txt',function (err,data) { 103 if(err){ 104 return console.error(err) 105 } 106 console.log('异步读取文件数据:'+ data.toString()) 107 }) 108 }) 109 110 111 112 113 读取文件 114 fs.read(fd,buffer,offset,length,position,callback) 115 fd:通过fs.open()方法返回的文件描述符 116 buffer:输入写入的缓冲区 117 offset:缓冲区写入的写入偏移量 118 length:要从文件中读取的字节数 119 position:文件读取的起始位置: 120 callback:三个参数:err,bytesRead,burrer,/错误信息/读取的字节数/缓冲区对象 121 var fs = require("fs"); 122 var buf = new Buffer.alloc(1024); 123 124 console.log("准备打开已存在的文件!"); 125 fs.open('input.txt', 'r+', function(err, fd) { 126 if (err) { 127 return console.error(err); 128 } 129 console.log("文件打开成功!"); 130 console.log("准备读取文件:"); 131 fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){ 132 if (err){ 133 console.log(err); 134 } 135 console.log(bytes + " 字节被读取"); 136 137 // 仅输出读取的字节 138 if(bytes > 0){ 139 console.log(buf.slice(0, bytes).toString()); 140 } 141 }); 142 }); 143 144 145 146 关闭文件:fs.close(fd,callback) 147 fd:通过fs.open()方法返回的文件描述符; 148 callback:回掉函数,没有参数 149 var fs = require('fs') 150 var buf = new Buffer.alloc(1024) 151 console.log('准备打开文件') 152 fs.open('input.txt','r+',function (err,fd) { 153 if(err){ 154 return console.error(err) 155 } 156 console.log("文件打开成功!"); 157 console.log("准备读取文件!"); 158 fs.read(fd,buf,0,buf.length,0,function (err,bytes) { 159 if(err){ 160 console.log(err) 161 } 162 if(bytes >0){ 163 console.log(buf.slice(0,bytes).toString()) 164 } 165 //关闭文件 166 fs.close(fd,function (err) { 167 if(err){ 168 console.log(err) 169 } 170 console.log('关闭文件成功') 171 }) 172 }) 173 }) 174 175 176 177 截取文件 178 fs.ftruncate(fd,len,callback) 179 fd:通过fs.open()方法 返回的文件描述符 180 len:文件内容截取的长度 181 callback:没有参数 182 var fs = require("fs"); 183 var buf = new Buffer.alloc(1024); 184 185 console.log("准备打开文件!"); 186 fs.open('input.txt', 'r+', function(err, fd) { 187 if (err) { 188 return console.error(err); 189 } 190 console.log("文件打开成功!"); 191 console.log("截取了10字节后的文件内容。"); 192 193 // 截取文件 194 fs.ftruncate(fd, 10, function(err){ 195 if (err){ 196 console.log(err); 197 } 198 console.log("文件截取成功。"); 199 console.log("读取相同的文件"); 200 fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){ 201 if (err){ 202 console.log(err); 203 } 204 205 // 仅输出读取的字节 206 if(bytes > 0){ 207 console.log(buf.slice(0, bytes).toString()); 208 } 209 210 // 关闭文件 211 fs.close(fd, function(err){ 212 if (err){ 213 console.log(err); 214 } 215 console.log("文件关闭成功!"); 216 }); 217 }); 218 }); 219 }); 220 删除文件fs.unlink(path,callback) 221 var fs = require('fs') 222 console.log('准备删除文件') 223 fs.unlink('input.txt',function (err) { 224 if(err){ 225 return console.error(err) 226 } 227 console.log('文件 删除成功') 228 }) 229 230 231 创建目录:fs.mkdir(path[,mode],callback) 232 path:文件路径; 233 mode:设置目录权限;默认为0777; 234 callback:回掉函数,没有参数 235 var fs = require('fs') 236 console.log('创建目录/node Project/test') 237 fs.mkdir('./index',function (err) { 238 if(err){ 239 return console.error(err) 240 } 241 console.log('创建目录成功') 242 }) 243 244 245 读取目录 246 fs.readdir(path,callback) 247 var fs=require('fs') 248 console.log('查看/index目录') 249 fs.readdir('./index/',function(err,files){ 250 if(err){ 251 return console.error(err) 252 } 253 files.forEach(function(file){ 254 console.log(file) 255 }) 256 }) 257 258 259 260 261 // 删除目录: 262 // fs.rmdir(path,callback) 263 var fs= require('fs') 264 //执行前创建一个空的目录 265 console.log('准备删除目录./delete') 266 fs.rmdir('./delete',function (err) { 267 if(err){ 268 return console.error(err) 269 } 270 console.log('读取/delete目录') 271 fs.readdir('./delete',function (err,files) { 272 if(err){ 273 return console.error(err) 274 } 275 files.forEach(function (file) { 276 console.log(file) 277 }) 278 }) 279 })