nodejs
环境变量
- 当我们在命令行窗口打开一个文件或调用一个程序时,系统会首先在当前目录下寻找文件程序,如果找到了直接打开,如果没找到会依次到环境变量path的路径中寻找,否则报错,类似于作用域链。
- 将一些经常需要访问的程序和文件的路径添加到path中,这样我们就可以在任意位置来访问这些文件和程序了。
进程和线程
进程
- 负责为程序的运行提供必备的环境
- 进程就相当于工厂中的车间
线程
- 线程计算机中的最小的计算单位,线程负责执行进程中的程序
- 线程相当于工厂中的工人
单线程
- js是单线程
多线程
node简介
- 能够在服务器端运行的JavaScript环境
- 处理不了并发量过高的情况,基于web的轻量级应用
- node是单线程,处理速度很快,对服务器硬件要求低。但是处理不了过多的用户,此时只能用分布式。
node基础
模块化
-
在node中,一个js文件就是一个模块
-
在node中,通过require()函数来引入外部的模块,require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块
-
使用require()引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块
-
在node中,每一个js文件中的js代码都是独立运行在一个函数中的function(){},在全局里看不到,所以一个模块中的变量和函数在其他模块中无法访问
-
在node中向外部暴露属性或方法,用exports,将需要暴露给外部的变量或方法设置为exports的属性即可
1 2 3 4exports.x = "我是02.module.js中的x" exports.add = function(a,b){ return a+b }
模块标识
- 使用require()引入外部模块时,使用的就是==模块标识==,我们可以通过模块标识来找到指定的模块
核心模块
-
由node引擎提供的模块
-
核心模块的标识就是模块的名字
1var fs = require("fs")
文件模块
- 由用户自己创建的模块
- 文件模块的标识就是文件的路径(绝对,相对)
全局对象
-
global,它的作用和window类似
-
在全局中创建的变量都会作为global的属性保存
-
在全局中创建的函数都会作为global方法保存
1 2{a = 10 log(global.a)}//argunments.callee当前执行的函数对象 -
node在执行模块中的代码时,它会在代码的最顶部,添加function(exports,require,module,_filename,_dirname){
在代码的最底部,添加如下代码 }
-
实际上模块中的代码都是包装在一个函数中执行的,并且在函数执行时,同时传递进了5个实参
实参 exports 该对象用于将变量或函数暴露到外部 require 函数,用来引入外部的模块 module 代表的是当前模块自身,exports就是module的属性,可以使用exports导出,也可以使用module.exports导出 _filename 当前模块的完整路径 _dirname 当前模块所在文件夹的完整路径
exports和module.exports
-
通过exports只能使用.的方式来向外暴露内部变量
-
module.exports既可以通过.的方式,也可以直接赋值
1 2module.exports.xxx = xxx module.exports = {}
包
- 包实际上就是一个压缩文件,解压以后还原为目录。符合规范的目录,应该包含
文件名 package.json 描述文件 bin 可执行二进制文件 lib js代码 doc 文档 test 单元测试
2.package.json中的属性含义,json文件中不能写注释
| 属性名 | |
|---|---|
| dependencies | 依赖的其他包 |
| description | 描述该包的作用 |
| devDependencies | 开发环境依赖 |
| name | 名字,用于require |
| version | 版本 |
| keywords | 关键字,用于搜索 |
| maintainers | 贡献者 |
| contributors | 维护者 |
| bugs | 提交bug地址 |
| licenses | 协议 |
| repositories | 仓库 |
| homepage | 主页 |
| os | 系统 |
npm简介
- Node Package Manager
- 对于node而言,npm帮助其完成了第三方模块的发布,安装和依赖。借助NPM,node与的三方模块之间形成了很好的一个生态系统。
npm命令
| 命令 | |
|---|---|
| npm-v | 查看版本 |
| npm | 帮助说明 |
| npm init | 创建package.json文件 |
| npm search 包名 | 搜索模块包 |
| npm install 包名 | 在当前目录安装包 |
| npm install 包名 -g | 全局模式安装包(一般都是一些工具,在计算机里用的,不是在项目中用的) |
| npm install 包名 –save | 安装包并添加自己初始化的package.json的依赖中 |
| npm remove 包名 | 删除包 |
| npm install | 下载当前项目所依赖的包 |
- 在需要安装npm包的目录下用npm init来初始化package.json文件
- 通过npm下载的包,通过包名引入即可
- node在使用模块名引入模块时,会首先在当前目录的node_modules中寻找是否含有该模块,如果有,则直接使用,如果没有则再去上一级目录寻找,知道找到为止,直到磁盘的根目录,没有则报错
Buffer缓冲区
-
Buffer的结构和数组很像,操作的方法也和数组类似
-
数组中不能存储二进制文件,而buffer就是专门存储二进制文件的
-
Buffer式node中的核心模块,使用buffer不用引入模块直接使用
-
在buffer中存储的都是二进制数据,但是在显示的时候都是以16进制的形式显示
-
1 2buffer.length //占用内存的大小,一个汉字占用3个字节,一个字母占用1个字节(8位二进制) str.length //字符串的长度 -
buffer的构造函数已经废弃了
创建和写入
| API | |
|---|---|
| Buffer.alloc(size) | 创建一个指定大小的buffer,且把内存的数据清空,都为0 |
| Buffer.allocUnsafe(size) | 创建一个指定大小的buffer,但是buffer中可能含有敏感数据,不会清空内存,但是这个性能更好 |
| Buffer.from(str) | 将一个字符串转化内buffer |
| buf.toString | 将缓冲区中的数据转换为字符串 |
|
|
==注意==:
- buffer的长度一旦确定,就无法改变,因为buffer是直接操作内存的,alloc(10)就是直接分配10个字节的连续的内存空间
- 如果超过8位二进制【0-256),则取后8位
读取
- buf[index]
- 调用buf.toString(),可以直接把缓冲区中的数据转为字符串
|
|
fs
- 通过node来操作系统中的文件
引入
- const fs = reqire(‘fs’)
同步文件
-
打开文件
fs.openSync(path,flags[,mode])
path 要打开文件的路径 flags 打开文件要做的操作类型 r:只读的 w:可写的 mode 设置文件的操作权限,一般不传 返回值:该方法会返回文件的描述符作为结果,我们可以通过该描述符来对文件进行各种操作
-
写入内容
fs.writeSync(fd,string[,position[,ecoding]])
fd 文件的描述符,需要传递要写入的文件的描述符(变量名) string 要写入的内容 position 写入的起始位置 ecoding 写入的编码,默认是utf-8 3.关闭文件
fs.closeSync(fd)
1 2 3 4 5 6let fs = require('fs') let fd = fs.openSync('hello.txt','w') fs.writeSync(fd,"今天天气真不错",20) fs.closeSync(fd)
异步文件
-
打开
fs.open(path,flags[,mode],callback)
除了callback是回调函数外,其他和同步相同,两个参数
err:错误对象,如果没有错误则为null
fd:文件的描述符
-
写入
fs.write(fd,callback)
-
关闭
fs.close(fd,callback)
|
|
简单文件
异步:fs.writeFile(file,data[,options],callback)
==注意==:options是可选项,默认写入w,utf-8,{flag:‘r’}进行修改,mode:文件权限
同步:fs.writeFileSync(file,data[,options])
|
|

如果要写磁盘的位置用绝对路径
流式文件
- 同步,异步,简单文件的写入都不适合大文件的写入,性能较差,容易导致内存溢出
可写流
fs.createWriteStream(path[,options]) //文件路径和配置参数
只要流存在就可以一直写入文件内容
|
|
监听
-
可以通过监听流的open和close事件来监听流的打开和关闭,用once事件监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14let fs = require('fs') let ws= fs.createWriteStream('hello3.txt') //向文件中输出内容 ws.write("通过可写流写入文件内容") ws.write("通过可写流写入文件内容") ws.write("通过可写流写入文件内容") ws.once('open',function () { console.log("流打开了") }) ws.once('close',function () { console.log("流关闭了") }) ws.end() //这里不能用close,相当于拔掉了水管的输出端,end是输入端
文件读取
同步
异步
简单
fs.readFile(path[,options],callback)
fs.readFileSync(path[,options]) //通过返回值
| path | 要读取的文件路径 |
| options | 读取的选项 |
| callback(err,data) | 回调函数,读取返回的内容 |
|
|
流式
- 如果文件小,只读一次
- 如果文件大,会分多个buffer读取,每次65536个字节的数据,避免占用大量内存空间
|
|
读取后写入其他文件,注意可写流要在可读流关闭时关闭
|
|
简单的写法
rs.pipe(ws)
|
|
其他方法

callback参数err,data

watchFile中的functionn(curr,prev)
这两个参数都是stats对象,可以用属性
options是对象,可以修改文件的监视时间频率
formidable模块
https://www.cnblogs.com/abab301/p/9489000.html
bcrypt加密



文件上传
前端读取

后端




==注意==:
- 不能直接保存path,用户是通过url访问服务器的资源,url的/实际就是服务器端的public文件夹,所以要split(‘public’)
