Node 知识
又称 cmd 窗口、终端、shell
打开方式:
前面显示的为目前所在的目录
常用的命令
环境变量(Windows 系统中的变量)
nodejs 是一个能够在服务器端运行 js 的开放源代码、跨平台的 js 运行环境
node 采用 google 开发的 v8 引擎运行 js 代码,使用 event-driven、non-blocking I/O 模型,使其轻量又高效
官网下载安装包,安装即可
推荐使用 nvm 管理 node 版本
安装完成后,打开命令行窗口,输入 node -v,如果出现版本号,则安装成功
安装完成后,会自动安装 npm 包管理器
运行 node,进入 node 命令行窗口,可以直接运行 js 代码
node
> var i = 0
> console.log(i)
还可以直接运行 js 文件
node hello.js
在 node 中,一个 js 就是一个模块
在 Node 中,每一个 js 文件中的 js 代码都是独立运行在一个函数中,而不是全局作用域,所以一个模块中的变量和函数在其他模块中无法访问
我们可以通过 exports 来向外部暴露变量和方法,只需要将要暴露给外部的变量或方法设置为 exports 的属性即可
exports.x = "我是 module.js中的x"
exports.fn = function(){}
在 Node 中有一个全局对象 global,它的作用和网页中 window 类似,在全局中创建的变量都会作为 global 的属性保存,在全局中创建的函数都会作为 global 的方法保存
var a = 10;
console.log(global.a);
arguments
在 node 执行模块中的代码时,它首先会在代码的最顶部添加代码 function(exports, require, module, __filename, __dirname){,在代码的最底部,添加代码 }
实际上模块中的代码都是包装在一个函数中执行的,并且在函数执行时,同时传递进了 5 个实参(arguments.length 查看参数长度)
exports.xxx = xxx
module.exports.xxx = xxx
module.exports = {
name = "swk"
age = 15000
sayName = function{
console.log(name)
}
}
在 node 中通过 require() 函数来引入外部的模块,require() 可以传递一个文件的路径作为参数,node 将会自动根据该路径来引入外部模块,这里的路径如果使用相对路径,必须以 . 或 .. 开头
使用 require 引入模块后,该函数会返回一个对象,这个对象代表的是引入的模块
var md = require("./module.js");
console.log(md)
模块分为两大类
CommonJS 规范的提出,主要是为了弥补当时 JavaScript 没有标准的缺陷
CommonJS 规范为 JS 制定了一个美好的愿景,希望 JS 能够在任何地方运行
CommonJS 规范对模块的定义十分简单
包实际上就是一个压缩文件,解压以后还原为目录
符合规范的目录,应该包含如下文件:
{
"name": "包名",
"version": "v1.0.0",
...
"dependencies": {}, // 依赖
"description": "描述",
"devDependencies": { // 开发依赖
...
}
}
包描述文件用于表达非代码相关的信息,它是一个 JSON 格式的文件—— package.json,位于包的根目录下,是包的重要组成部分
package.json 中的字段(JSON 中不能写注释)
通过 npm run 可以查看当前可执行的脚本命令(script 字段),npm run 脚本名称 可以执行对应的脚本命令
CommonJS 包规范是理论,NPM 是其中一种实践
对于 Node 而言,NPM 帮助其完成了第三方模块的发布、安装和依赖等。借助 NPM,Node 与第三方模块之间形成了很好的一个生态系统
包管理工具,用于 Node 模块的管理,除了 npm 之外,还有 yarn、cnpm、pnpm 等
现在推荐使用 pnpm 代替 npm,pnpm 是一个快速、零配置的 Node 包管理工具,它使用硬链接和符号链接来降低磁盘空间的使用,它的速度也非常快,它的速度是 npm 的 35 倍,yarn 的 23 倍
淘宝镜像: npm.taobao 组织网
一般不直接设置官方原版 npm 替换为其他源,可以使用 cnpm
SH
npm install -g cnpm --registry=https://registry.npmmirror.com
注:
Buffer 的就结构和数组很像,操作的方法也和数组类似
数组中不能存储二进制的文件,而 buffer 就是专门用来存储二进制数据的
使用 buffer 不需要引入模块,直接使用即可
var str = "hello"
// 将一个字符串保存到buffer中
var buf = Buffer.from(str)
console.log(buf)
console.log(buf.length,str.length) // 占用内存的大小,字符串的长度
在 buffer 中存储的都是二进制数据,但是在显示的时候都是以 16 进制的形式显示的,buffer 中每一个元素的范围是从 00 到 ff (0255) 0000000011111111 8 位(bit) = 1字节(byte),buffer 中的一个元素占用内存的一个字节
ps:一个汉字 3 字节,一个英文字母 1 字节
buffer 的大小一旦确定,则不能修改,Buffer 实际上是对底层内存的直接操作
// 创建一个指定大小的buffer
var buf = new Buffer(10) // 10个字节的buffer
// buffer构造函数都是不推荐使用的
var buf2 = Buffer.alloc(10) // 全都是00
buf2[0] = 88
buf2[1] = 255
buf2[2] = 0xaa
buf2[3] = 556
// 1000101100截取后八位
buf2[10] = 15 // 没改变
// 只要数字在控制台或页面中输出一定是10进制
console.log(buf2[2])
console.log(buf2[2].toString(16)) // 可以这样转为16进制显示
var buf3 = Buffer.allocUnsafe(10) // 创建一个指定大小的buffer,但是buffer中可能含有敏感数据,不全为00
nodejs 国内网
文件系统简单来说就是通过 Nodejs 来操作系统中的文件
在 Node 中,与文件系统的交互是非常重要的,服务器的本质就是将本地的文件发送给远程的客户端
Node 通过 fs 模块来和文件系统进行交互
fs 模块提供了一些标准文件访问 API 来打开、读取、写入文件,以及与其交互
要使用文件系统,需要先引入 fs 模块,fs 是核心模块,直接引入不需要下载;要使用 fs 模块,首先需要对其进行加载
const fs = require('fs')
同步文件的写入
操作步骤:
var fs = require("fs");
var fd = fs.openSync("hello.txt", "w");
// console.log(fd)
fs.writeSync(fd, "这是写入的内容")
异步文件写入:
var fs = require("fs")
var f
fs.open("hello.txt","w",function(err, fd){
// console.log('回调函数中的代码') // callback中的代码会在读取完毕之后执行
if(!err){
f = fd
}else{
console.log(err)
}
})
console.log("open下的代码") // 能比上面的更早执行
var fs = require("fs")
fs.open("hello.txt","w",function(err, fd){
if(!err){
fs.write(fd, "这是异步写入的内容",function(err) {
if(!err){
console.log('写入成功')
}
fs.close(fd, function(err){
if(!err){
console.log('文件已关闭')
}
})
})
}else{
console.log(err)
}
})
fs.writeFile(file, data[, options], callback)
var fs = require('fs')
// 路径也可以C:/Users/Shinlo/Desktop/hello.txt
fs.writeFile("C:\\Users\\Shinlon\\Desktop\\hello.txt", "这是通过writeFile写入的内容", {flag: "a"}, function(err){
if(!err){
console.log('写入成功')
}else{
console.log(err)
}
})

fs.writeFileSync(file, data[, options])
同步简单写入
同步、异步、简单文件的写入都不适合大文件的写入,性能较差,容易导致内存溢出
流式文件写入:
fs.createWriteStream(path[, options])
var fs = require("fs")
var ws = fs.createWriteStream("hello.txt")
// 可以通过监听流的open和close事件来监听流的打开和关闭
// ws.on("open", function{ // on绑定一个长期有效的事件
ws.once("open", function{ // once绑定一次性的事件,在触发一次之后事件自动失效
console.log("流打开了")
})
ws.once("close", function{
console.log("流关闭了")
})
// 通过ws向文件中输出内容
ws.write("通过可写流写入文件的内容1")
ws.write("通过可写流写入文件的内容2")
ws.write("通过可写流写入文件的内容3")
// 只要流还存在就可以接着写入
// 关闭流
// ws.close() // 这个在传入的方向断开流,文件没到管子里
ws.end() // 在传出的这一方断开流,数据已经在管子里了
同步文件读取、异步文件读取、简单文件读取
fs.readFile(path[, options], callback)
fs.readFileSync(path[, options])
var fs = require("fs")
var path="C:/Users/Shinlon/a.mp3"
fs.readFile("hello.txt", function(err, data) {
if(!err) {
console.log(data) // buffer通用性更高
// console.log(data.toString())文本可以,其他不行
fswriteFile("hello.mp3", data, function(err) {
if(!err) {
console.log("文件写入成功")
}
})
}
})
流式文件读取
var fs = require("fs")
// 创建一个可读流
var rs = fs.createReadStream("an.jpg")
// 监听流的开启和关闭
rs.once("open", function() {
console.log("可读流打开了")
})
rs.once("close", function() {
console.log("可读流关闭了")
})
// 读取一个可读流中的数据,必须要为可读流绑定一个 data 事件,data 事件绑定完毕,它会自动开始读取数据
rs.on("data", function(data) {
console.log(data) // 参数就是数据 data.length 最大 65536 字节
})
可读流、可写流复制一个大文件
var fs = require("fs")
var rs = fs.createReadStream("an.jpg")
var ws = fs.createWriteStream("an.jpg")
rs.once("open", function() {
console.log("可读流打开了")
})
rs.once("close", function() {
console.log("可读流关闭了")
// 数据读取完毕,关闭可写流
ws.end()
})
ws.once("open", function() {
console.log("可写流打开了")
})
ws.once("close", function() {
console.log("可写流关闭了")
})
rs.on("data", function(data) {
ws.write(data)
})
简单的方式
var fs = require("fs")
var rs = fs.createReadStream("an.jpg")
var ws = fs.createWriteStream("an.jpg")
rs.once("open", function() {
console.log("可读流打开了")
})
rs.once("close", function() {
console.log("可读流关闭了")
})
ws.once("open", function() {
console.log("可写流打开了")
})
ws.once("close", function() {
console.log("可写流关闭了")
})
// pipe()可以将可读流中的内容直接输出到可写流中
rs.pipe(ws)
验证路径是否存在
var fs = require("fs")
var isExists = fs.exitsSync("a.mp3")
// console.log(isExists)
获取文件信息
fs.stat("a.mp3", function(err, stat) {
console.log(stat)
})
stat 参数的一些属性、方法
删除文件
fs.unlinkSync("hello.txt")
列出文件
fs.readdir(".", function(err, files) {
if(!err){
console.log(files)
}
})
截断文件
fs.truncateSync("hello.txt", 3)
建立目录
fs.mkdirSync("hello")
删除目录
fs.rmdirSync("hello")
重命名文件和目录
fs.rename("a.mp3", "new.mp3", function(err) {
if(!err){
console.log("success")
}
})
监视文件更改写入
fs.watchFile("hello.txt", function {
console.log(prev.size)
console.log(curr.size)
})
时间间隔,配置选项中
fs.watchFile("hello.txt", { interval: 1000 }, function {
console.log(prev.size)
console.log(curr.size)
})
