简介
Node.js是一个服务端JS运行环境
单线程
CommonJS
缺陷:
没有模块化
标准库较少
没有借口标准
缺乏管理系统
NodeJS中, 一个js文件就是一个模块
引入别的模块
通过require()引入模块
如果是相对路径, 一点得以.或者..开头
1 | require("./02.module.js"); |
使用require()引入模块后, 该函数返回一个模块, 这个对象代表的事引入的模块
1 | var md = require("./02.module.js"); |
在node中, 每个js文件中的代码, 都是独立运行在一个函数中
不是全局作用域, 所以一个模块的变量和函数在其他模块无法访问
exports
可以通过exports 来向外部暴露变量和方法
1 | exports.x = "我是exports x"; |
module.exports 可以通过赋值的方式暴露变量, exports不行
1 | module.exports = { |
模块分成两大类
- 核心模块
- node引擎提供的模块
- 核心模块的标识, 就是模块的名字
- 文件模块
- 用户自己创建的模块
- 文件模块的标识, 是文件袋路径
在全局中创建的变量函数都会作为global的属性属性或者方法保存
1 | a = 10; |
当node执行模块中的模块时, 会在代码最顶部添加一行代码
1 | function(exports,require, module, _filename, _dirname){ |
exports
- 将变量暴露到外部
require
- 引入外部模块
module
- 模块本身
- exports就是module的属性
__filename
- 文件绝对路径
__dirname
- 文件夹路径
package
包, 实际上是一个压缩文件, 解压后为原目录.
由包结构和包描述文件组成
符合规范的目录包含以下文件:
- package.json — 必须的描述文件
- bin - 可执行的二进制文件
- lib - js代码
- doc - 文档
- test - 单元测试
WebStrom自动生成的文件package.json
1 | { |
包描述文件用于表达非代码相关的信息, 是一个JSON文件
不可以在里面写注释
NPM
Node Package Manager
NPM帮助Node完成了第三方模块的发布安装和依赖
npm search 搜索
1 | npm search math |
npm init
可以创建一个package.json
npm install
1 | npm install math |
npm其他命令
- npm -v
- npm version
- npm remove/r 包名
- npm install 包名–save 安装包并添加依赖
- npm install 不加包名, 下载当前项目依赖的包
- npm install 包名 -g 全局安装包 (全局安装包一般都是一些工具)
淘宝npm镜像
1 | npm install -g cnpm --registry=https://registry.npm.taobao.org |
Buffer
结构和数组很像, 操作的方法也和数组类似
专门用来存二进制数据
不需要引入模块, 可以直接使用
每个数据都是二进制, 但是显示的时候都是十六进制
buffer中一个元素, 占用一个字节Byte – 8bit
buffer 大小, 一但确定不再修改
- 因为buffer实际上是对底层内存的直接操作
1 | var str = "Hello"; |
创建指定大小的buffer
buffer所有构造函数都不推荐使用
1 | var buf2 = new Buffer(10); //10个字节的buffer |
通过索引操作buffer中的元素
1 | var buf2 = Buffer.alloc(10);//10个字节的buffer |
File System
fs模块
1 | var fs = require("fs"); |
同步和异步调用
- 同步会阻塞程序运行
- 异步不会阻塞程序运行
同步文件写入
1 | var file = fs.openSync(path, flags[, mode]) |
- path 要打开的文件路径
- flags 要做的操作运行
- 读写, 只读, 只写
- r , w
- mode 设置文件操作权限, 一般不传
方法返回一个文件描述符作为结果, 可以通过描述符文件对文件进行各种操作
1 | fs.write(fd, string[, position[, encoding]]) |
- fd 文件描述符, 需要传递要写入文件的描述符
- string 需要写入的内容
1 | fs.closeSync(fd) |
关闭文件
异步写入文件
1 | fs.open("hello.txt","w",function(){ |
没有返回值, 但是有回调函数
- 结果都是通过回调函数的参数返回, 参数有:
- err 错误
- fd 文件描述符
异步写入
1 | fs.open("hello.txt","w",function(err, fd){ |
简单的文件写入
1 | fs.writeFile(file, date[, options], callback) |
- file 文件名
- data
- opions
- callback 回调函数
1 | var fs = require("fs"); |
默认情况下, 覆盖原文件内容
追加内容到flags
- a 打开文件用于追加, 没有则创建
1 | fs.writeFile("hello.txt", "something",{flag:"a"}, function(err){ |
流式文件写入
普通写入不适合大文件写入, 性能较差, 容易导致内存溢出
创建一个可写流
1 | fs.createWriteStream(path[, options]) |
- path 文件路径
- options 配置都参数
1 | var ws = fs.createWriteStream("hello4.txt"); |
1 | ws.wirte("wirte something"); |
可以持续写入
可以通过监听流的open和close事件来监听流的打开和关闭
1 | ws.on("open", function(){ |
关闭要用end不能用close
1 | ws.end(); |
简单文件读取
1 | fs.readFile("an.jpg", function(err,data){ |
流式文件读取
1 | var rs = fs.createReadStream("an.jpg"); |
如果读取通过可读流读取数据, 必须绑定一个data事件, 绑定完毕, 会自动开始读取数据
数据为回调函数
1 | var ws = fs.createWriteStream(a.mp3); |
更简单的方法
1 | rs.pipe(ws); |
pipe可以直接将可读流中的内容直接输出到可写流中;
其他file方法
fs.exits(path, callback);
fs.stat();
- 返回一个对象, 有对象状态相关信息
fs.unlink(path, callback)
- 删除文件
fs.readdir(“.”, function(err, files){})
- files 是文件数组
fs.truncateSync(“hello.txt”, 10)
- 截断文件, 设置文件成指定大小
fs.mkdir(path[, mode], callback)
- 创建目录
fs.rmdir(path[, mode], callback)
fs.rename(oldPath, newPath, callback)
- 重命名
- 也可以间接实现剪切操作
fs.watchFile(filename[, options], listener)
- 监视文件的修改
- 参数:
- filename
- options
- listener 回调函数, 文件发生时, 函数会被执行
- 有两个参数:
- curr
- prev
- 都是stats对象