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.js31 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 /258 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 error22 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,error42 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.gz67 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.js20 // function world(){ 21 // var name ;22 // this.setName = function (thyName) { 23 // name = thyName24 // };25 // this.setHello = function () { 26 // console.log('hello ' + name)27 // }28 // }29 // module.exports = world;30 //31 // // hello.js32 // 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 分析:打印出hello12 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 = start24 25 26 // router.js27 function route(pathname) {28 console.log('About to route a request for' +pathname)29 }30 exports.route = route31 // 如何将路由和服务器整合起来:32 33 34 // index.js35 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:\Users\yangguoe\Desktop\node Project\hello.js 5 _dirname:当前执行脚本所在的目录 6 console.log( __dirname )////C:\Users\yangguoe\Desktop\node 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 })