目录:
一、node.js介绍
二、node.js有哪些特点
三、下载安装node.js,配置环境变量
四、node.js开发网站和传统PHP等开发网站的区别
五、REPL介绍
六、helloworld程序
七、案例:输出一个三角形
八、fs写入文件和读取文件
九、__dirname和__filename获取正在执行的js文件的路径
十、使用path模块进行路径拼接
十一、通过http模块构建一个简单的http服务程序
十二、Buffer
一、node.js介绍 <--返回目录
1.1、node.js是什么
官网首页总结:Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时。
1)node.js是一个开发平台,就像java开发平台、.net开发平台、PHP开发平台、Apple开发平台一样。
- 什么是开发平台:有对应的编程语言、有语言运行时、有能实现特定功能的API(SDK Software Development Kit)
2)node.js平台使用的编程语言是JavaScript。
3)node.js平台是基于Chrome V8 JavaScript 引擎构建。
1.2、node.js可以做什么
1)基于node.js可以开发控制台程序(命令行程序、CLI程序)、桌面应用程序(GUI,要借助node-webkit、electron等框架实现)、web应用程序(网站)
2)PHP开发技术栈:LAMP - Linux Apache MySQL PHP
3)node.js全栈开发技术栈:MEAN- MongoDB Express Angular Node.js
二、node.js有哪些特点 <--返回目录
1)事件驱动:当事件被触发,执行传递过去的回调函数
2)非阻塞I/O模型:当执行I/O操作时,不会阻塞线程
3)单线程
4)拥有世界最大的开源库生态系统-npm
node.js在处理高并发、I/O密集场景性能优势明显。
- CPU密集:压缩、解压、加密、解密
- I/O密集:文件操作、网络操作、数据库操作
web常见场景:静态资源读取、数据库操作、渲染页面。
node.js的单线程:单线程只是针对主进程,I/O操作系统底层多线程调度。
三、下载安装node.js,配置环境变量 <--返回目录
node.js官方网站:https://nodejs.org/
中文网: http://nodejs.cn/
中文社区:https://cnodejs.org/
下载win 64为安装包:node-v10.16.0-x64.msi,双击安装
为了在任何目录下都可以使用node和npm命令,将这两个命令添加到环境变量path。我安装node时默认就添加到了环境变量。
四、node.js开发网站和传统PHP等开发网站的区别 <--返回目录
1)传统php、java、asp.net开发web程序需要web容器
2)node.js本身就是web服务器
- 接收用户请求后,根据不同的请求直接做对应处理
- 把处理后的结果返回给浏览器
五、REPL介绍 <--返回目录
1)REPL全称Read Eval Print Loop交互式解释器
- R 读取,读取用户输入,解析输入js数据结构并储存在内存中
- E 执行,执行输入的数据结构
- P 打印,输出结果
- L 循环,循环操作以上步骤直到用户两次按下Ctrl+c按钮退出
2)在REPL中编写程序,类似于浏览器开发人员工具中的控制台功能。
3)直接在控制台输入node命令,进入REPL环境。
4)按两次Ctrl+c 或者输入 .exit ,退出REPL界面
六、helloworld程序 <--返回目录
新建一个helloworld.js
var m = 10;
var n = 20;
function add(x, y) {
return x + y;
}
console.log(m + "和"+ n + "相加,等于" + add(m,n));
在包含helloworld.js文件的目录下,shift+右键,在此处打开命令窗口;输入命令 node hel(tab补全),控制台会打印结果。
七、案例:输出一个三角形 <--返回目录
process模块是全局模块,直接使用;
for(var i = 0; i <10; i++) {
for(var j = 0;j <=i; j++) {
process.stdout.write("* ");
}
console.log();
}
八、fs写入文件和读取文件 <--返回目录
process模块是全局模块,直接使用;fs不是全局模块,要用require加载
fs写入文件:
// 加载文件操作fs模块
var fs = require("fs");
// 文件写入
// fs.writeFile('文件路径','数据','选项',function(){});
fs.writeFile('./a.txt','hello world', 'utf-8', (err) => {
// 如果err===null,表示写入文件成功
// 只要err不是null,就表示写入文件失败
if (err) {
throw err;
console.log("数据写入失败: " + err);
} else {
console.log("数据写入成功");
}
});
fs文件追加内容:
fs.appendFile('./test.txt', 'bbbb', 'utf8', err => {
console.log('done')
})
fs读取文件:
// 加载文件操作fs模块
var fs = require("fs");
// fs.ReadFile('文件路径','选项',function(){});
// 文件路径'a.txt'是相对于执行node命令的路径
fs.readFile('./a.txt','utf-8',(err,data) => {
if (err) {
throw err;
console.log("数据读取失败");
} else {
console.log(data);
}
});
fs.stat() 判断是文件还是文件夹
fs.stat('./a.js', (err, stats) => {
if (err) {
console.log('文件不存在'); // 一般可以用来判断文件是否存在
return;
}; console.log(stats.isFile());
console.log(stats.isDirectory()); console.log(stats);
});
fs.rename() 重命名
fs.rename('./text', 'test.txt', err => {
if(err) throw err; console.log('done!');
});
fs.unlink() 删除
fs.unlink('./test.txt', err => {});
fs.readdir() 读取文件夹内容
fs.readdir('../', (err, files) => {
if (err) throw err; console.log(files);
})
fs.mkdir() 创建目录
fs.mkdir('test', err => {});
fs.watch() 监视文件或文件夹的变化
fs.watch('./', {recursive: true}, (eventType, filename) => {
console.log(eventType, filename);
});
fs同步的方法
const fs = require("fs"); // 同步的读取
var data = fs.readFileSync("./test.txt", 'utf8'); console.log("文件读取完成, data: ", data); //同步的写入
fs.writeFileSync("./test.txt", '很好', 'utf8'); //同步的追加
fs.appendFileSync("./test.txt", '呵呵', 'utf8');
九、__dirname和__filename获取正在执行的js文件的路径 <--返回目录
前面的程序都是在hello.js所在目录执行node ./hello.js命令。如果进到c盘,执行node D:\hello.js命令,结果:
__dirname表示当前正在执行的js文件的所在目录;__filename表示当前正在执行的js文件的完整路径
//fs读取文件
// 加载文件操作fs模块
var fs = require("fs");
// fs.writeFile('文件路径','选项',function(){});
// fs.readFile(__dirname+'\\a.txt','utf-8',(err,data) => {
fs.readFile(__dirname+'/a.txt','utf-8',(err,data) => {
if (err) {
throw err;
console.log("数据读取失败");
} else {
console.log(data);
}
});
所以,"./hello.js"中./是相对于执行node命令的路径,而不是相对于当前js文件的路径。
__dirname和__filename不是全局的,但是为什么使用的时候不需要通过require引入:
(
function ("__dirname", "__filename") {
//fs读取文件
// 加载文件操作fs模块
var fs = require("fs");
// fs.writeFile('文件路径','选项',function(){});
// fs.readFile(__dirname+'\\a.txt','utf-8',(err,data) => {
fs.readFile(__dirname+'/a.txt','utf-8',(err,data) => {
if (err) {
throw err;
console.log("数据读取失败");
} else {
console.log(data);
}
});
}
)("当前正在执行的js文件的所在目录","当前正在执行的js文件的完整路径");
总结:__dirname、__filename总是返回文件的绝对路径;
process.cwd()总是返回执行node命令所在文件夹;
require()方法总是相对当前文件;
pahth.resolve('./')是执行node命令所在文件夹
十、使用path模块进行路径拼接 <--返回目录
path会根据系统拼接成对应的路径,windows下格式是 \a\b\c
var path = require('path');
var str = path.join('/foo','bar','baz/asdf');
console.log(path);
process.stdout.write(str); // \foo\bar\baz\asdf
const path = require('path') // normalize: 将路径解析成标准的格式
console.log(path.normalize('/usr/local//bin')) // \usr\local\bin
console.log(path.normalize('/usr/local/../bin')) // \usr\\bin // resolve: 将相对路径解析成绝对路径
console.log(path.resolve('./')) // D:\当前文件所在目录名 // basename: 取文件名, dirname: 文件夹, extname: 扩展名
const pathName1 = path.basename('c:/a/b.js')
console.log(pathName1) // b.js
const pathName2 = path.basename('c:\\a\\b.js')
console.log(pathName2) // b.js const filePath = '/usr/local/bin/a.txt'
console.log(path.basename(filePath)) // a.txt
console.log(path.dirname(filePath)) // /usr/local/bin
console.log(path.extname(filePath)) // .txt console.log('='.repeat(50))
// parse format
const parseResult = path.parse(filePath)
console.log(parseResult) // {root:'/', dir:'/usr/local/bin', base:'a.txt', ext:'.txt', name:'a'}
// parseResult对象中dir和base优先级高,即有这个两个属性,其他属性值忽略掉。因为有dir和base属性就可以完全拼接出完整的文件名
console.log(path.format(parseResult)) // /usr/local/bin\a.txt
const path = require('path')
// sep delimiter win32 posix
console.log('当前系统下sep: ', path.sep)
console.log('win sep:', path.win32.sep)
console.log('posix sep', path.posix.sep) console.log('PATH: ', process.env.path)
console.log('当前系统下delimiter: ', path.delimiter) // delimiter是PATH的分隔符
console.log('win delimiter: ', path.win32.delimiter)
console.log('posix delimiter: ', path.posix.delimiter)
十一、通过http模块构建一个简单的http服务程序 <--返回目录
第一步:在d:/hello.js写代码:
// 加载http模块
var http = require("http"); // 创建一个http服务对象
var server = http.createServer(); // 监听用户的请求
server.on('request', function(req,res) {
res.setHeader('content-type','text/html;charset=utf-8');
res.write('<h1>hello 您好!</h1>');
res.end();//结束响应
}); // 开启服务
server.listen('8080', function() {
console.log('服务器已经启动。');
});
第二步:cmd窗口输入node D:\hello.js运行程序
第三步:浏览器输入http://localhost:8080。
十二、Buffer <--返回目录
Buffer用于处理二进制数据流,类似数组,但是Buffer大小固定。
构造Buffer
console.log(Buffer.alloc(5)) // 默认0填充
console.log(Buffer.alloc(5, 1)) //0x1填充
console.log(Buffer.allocUnsafe(5)) // 保持原有数据
console.log(Buffer.from([1, 2, 3]))
console.log(Buffer.from('test')) // 默认utf-8编码
console.log(Buffer.from('test', 'base64'))
Buffer的byteLength()、isBuffer()、concat()方法
/*
Buffer.byteLength()
Buffer.isBuffer()
Buffer.concat()
*/
console.log(Buffer.byteLength('test')) //
console.log(Buffer.byteLength('测试')) // 6, utf-8编码 console.log(Buffer.isBuffer({})) // false
console.log(Buffer.isBuffer(Buffer.from([1, 2, 3]))) // true const buf1 = Buffer.from('hello')
const buf2 = Buffer.from('世界')
const buf3 = Buffer.from('!')
const buf = Buffer.concat([buf1, buf2])
console.log(buf.toString()) // hello世界!
buf.length、buf.toString([encoding])、buf.fill(value[, start, end])
const buf = Buffer.allocUnsafe(10)
buf[2] = 0xff
console.log(buf.length)
console.log(buf) buf.fill(0xff)
console.log(buf) const buf2 = Buffer.from('hello world')
console.log(buf2.toString())
console.log(buf2.toString('base64'))
buf.equals()、buf.indexOf()
const buf1 = Buffer.from('test')
const buf2 = Buffer.from('test')
console.log(buf1.equals(buf2)) // 比较内容是否相同,true console.log(buf1.indexOf('te')) //
console.log(buf1.indexOf('abc')) // 找不到,返回-1
---