Nodejs学习笔记
中文文档-API 文档 | Node.js 中文网 (nodejs.cn)
Node.js
是一个基于V8 JavaScript engine的JavaScript运行环境,是一个应用程序。
在使用JavaScript代码时,要清楚它到底是在前端运行还是在后端运行。
作用
- 解析并运行
js
代码 - 操作系统资源(内存等),如果是浏览器就不能操作硬盘等。
应用场景
- app接口服务
- 网络聊天室
- 动态网站、个人博客等
- 后端的web服务(服务端的请求爬虫、代理请求{跨域})
- 前端项目打包(webpack、gulp)
nodejs的交互模式
使用node
进入交互模式。
但是这种模式并不常用。
使用nodejs执行文件
使用node + xxx.js
执行代码
在nodejs运行代码时,不能使用window
和’doucument’,其中的全局对象是global
Buffer(缓冲器)— 了解
Buffer是一个和数组类似的对象,不同的是Buffer是专门用来保存二进制数据的。
特点
- 大小固定: 在创建时就确定了,且无法调整
- 性能较好:直接对计算机内存进行操作
- 每一个元素大小为1个字节
创建Buffer
-
直接创建使用
Buffer.alloc
-
不安全的创建
Buffer.allocUnsafe
-
通过数组和字符串创建
Buffer.from
const buf_1 = Buffer.alloc(10); // 创建10个字节的
const buf_2 = Buffer.allocUnsafe(10);
const buf_3 = Buffer.from([1,23,4,4]);
const buf_4 = Buffer.from('dasdwd');
console.log(buf_1);
console.log(buf_2);
console.log(buf_3);// 与之对应的ascii吗
console.log(buf_4);// 与之对应的ascii吗
// 结果
<Buffer 00 00 00 00 00 00 00 00 00 00> // 2个16 进制 代表一个8进制
<Buffer 00 00 00 00 00 00 00 00 00 00>
<Buffer 01 17 04 04>
<Buffer 64 61 73 64 77 64>
虽然 alloc
和 allocUnsafe
均分配指定大小的 Buffer
(以字节为单位),但是 alloc
创建的 Buffer
会被使用零进行初始化,而 allocUnsafe
创建的 Buffer
不会被初始化。 这意味着,尽管 allocUnsafe
比 alloc
要快得多,但是分配的内存片段可能包含可能敏感的旧数据。
内容的读取和设置
-
读取和数组差不多
console.log(String.fromCharCode(buf_4[0]));// 把它转换为字符
-
把Buffer转换为字符串
console.log(buf_3.toString());
-
和数组一样
buf_3[0] = 99; // 当前要小于一个字节(也就是255),要不然会溢出
-
溢出
如果出现溢出的情况,会舍弃高于8位的内容。
比如说300 -> 1 0010 1100: 就回变成 0010 1100 -> 44
-
中文的问题
一个
utf-8
的字符占用3个字节。
文件系统–fs(file System)—重要
它是nodejs的内置模块,可以对计算机中的文件进行增删改查的操作。
异步文件写入
-
引 入文件描述符
在与位于文件系统中的文件进行交互之前,需要先获取文件的描述符。
文件描述符是使用
fs
模块提供的open()
方法打开文件后返回的// 1. 引入fs模块 const fs = require('fs'); //引入fs模块
-
写入文件
//2 调用方法 fs.writeFile('./index.html','hhhhhhh',{flag:a},function(err){ if(err) { console.log('写入失败'); console.log('失败错误为'+err); return; }else{ console.log('写入成功'); } });// 如果不存在,则自动创建
-
文件权限
0o666(八进制),在linux在的文件权限的管理方式
第一个6:所有者的权限
第二个6:所属组的权限
第三个6:其他人权限
权限分为:
- 4 可读
- 2 可写
- 1 可执行
- 6 是4+2得来的,也就就是可读写
- 777 最高权限
写入对象
let data = {
'name': 'dasda',
age: 123
}
// 使用JSON把它转换为字符串
let str = JSON.stringify(data);
const fs = require('fs');
fs.writeFile('./text', str, function (err) {
if (err) {
console.log('写入失败');
} else {
console.log('写入成功');
}
});
同步文件写入
fs.writeFileSync(file, data [.option])
option: encoding:编码,mode:权限,flag。
没有回调函数
同步写入和异步写入的区别
- 对于异步的文件写入,它的最后一个参数是毁掉函数,这个函数不会立即执行。 写入是异步执行的,代码的执行顺序和编写顺序是不一样的。
- 同步写入的执行顺序和编写顺序是一样的。
同步和异步的选择
-
如果需要做服务,那么就需要异步。如果使用同步就产生阻塞。
-
如果一些文件相关的处理,可以使用同步。
写入文件的场景
- 下载文件
- 安装文件
- 日志写入(程序日记)
- 数据库
- 网盘
写入流对象写入文件
// 1. 引入 fs模块
const fs = require('fs');
// 2. 创建写入流对象
const ws = fs.createWriteStream('./test.html');
// 3. 执行写入,不会覆盖之前的
ws.write('asdasd');
ws.write('123123');
// 4.关闭写入流
ws.close();
writeFile 和 createWriteStream的使用场景
写入次数较少的,可以使用writeFile
,如果是批量要写入,那就是用createWirteStream
。
读取文件
readFile()
异步读取
// 1. 引入 fs模块
const fs = require('fs');
// 2. 调用方法
fs.readFile('./test.html',function(err,data){
if(err){
console.log('读取失败');
console.log(err);
}else{
console.log(data.toString());
}
});
结果为:<Buffer 61 73 64 61 73 64 31 32 33 31 32 33>
。使用data.toString()
转换为字符串。
readFileSync
一次读取所有内容
// 1. 引入 fs模块
const fs = require('fs');
// 2. 调用方法
let data = fs.readFileSync('./test.html');
console.log(data.toString());
同步读取没有回调函数。直接返回Buffer。
流式读取文件
// 1. 引入 fs模块
const fs = require('fs');
// 2. 创建读取流
const rs = fs.createReadStream('./test.html');
// 3. 绑定事件 chunk 块(64k) 当读取完一块数据后触发,如果文件太大了,就一块一块的读取
rs.on('data',(chunk) => {
console.log(chunk.toString());
});
// 读取流打开事件
rs.on('open',() => {
console.log('读取流打开了');
})
比较
对于小文件读取和处理,那么就是用readFile
对于大文件读取,那么就是用createReadStream
复制文件
const fs = require('fs');
const ws = fs.createWriteStream('./test1.html');
const rs = fs.createReadStream('test.html');
rs.on('data', chunk=> {
// 写入文件
ws.write(chunk);
})
ws.close();
rs.close();
// 当然最简单的方式就是
rs.pipe(ws);
// 还有copy的api,自己看官网
移动文件+重命名
重命名
const fs = require('fs');
fs.rename('./test.html','.index.html' err=>{
if(err) throw err;
console.log('重命名成功')
})
移动文件
上述代码,后面的目标文件该目录就好了,当然还要加上文件名字。
文件删除
不会进行回收站
fs.unlink('./test.log', function(err){});
fs.unlinkSync('./move.txt');
文件夹操作
const fs = require('fs');
// 创建文件夹
fs.mkdir('./html',err=>{
if(err) throw err;
console.log('创建成功');
})
//读取文件夹(是读取文件夹下的文件的列表)
fs.readdir('./html/',(err,files) => {
if(err) throw err;
console.log(files);
})
// 删除文件夹,只能删除空文件夹,{recursive:true}递归删除所有文件
//fs.rmdir 已被取代
fs.rm('./html',{recursive:true},err => {
console.log(err);
})
判断是文件夹还是文件
const fs = require('fs');
fs.stat('./index',(err,stats) => {
console.log('是否为文件夹' + stats.isDirectory());
console.log('是否为文件' + stats.isFile());
})
练习
使用异步的时候,一定要考虑是否已经创建完成。
desktop
project
html
index.html
css
index.css
js
index.js
const fs = require('fs');
fs.mkdir('C:\\Users\\fujiaxu\\Desktop\\project',err => {
if (err) throw err;
// 因为这个异步创建的,project的里面文件的创建写在外面,那么不能保证projec 文件夹是创建完成了的
fs.mkdir('C:\\Users\\fujiaxu\\Desktop\\project\\html',err => {
if(err) throw err;
fs.writeFile('C:\\Users\\fujiaxu\\Desktop\\project\\html\\index.html','hhh',err => {
if(err) throw err;
})
});
fs.mkdir('C:\\Users\\fujiaxu\\Desktop\\project\\css',err => {
if(err) throw err;
fs.writeFile('C:\\Users\\fujiaxu\\Desktop\\project\\css\\index.css','hhh',err => {
if(err) throw err;
})
});
fs.mkdir('C:\\Users\\fujiaxu\\Desktop\\project\\js',err => {
if(err) throw err;
fs.writeFile('C:\\Users\\fujiaxu\\Desktop\\project\\js\\index.js','hhh',err => {
if(err) throw err;
})
});
})
回调地狱
api是异步的,回调函数里面写异步任务,上诉代码就是。、
可以使用promise解决