前端菜鸟查漏补缺--node.js篇(上篇)


关于node.js。我再前面项目中使用webpack搭建项目的时候有了解过。当时单纯只是说配置webpack和vue的时候需要。而没有真正的把它作为一个新的知识点来学习。其实现在node.js对于前端来说还是蛮重要的,还是要慢慢学习啊。
前面有文章介绍node.js的安装,这里就不再重新演示安装了。学习都需要自己动手去撸代码,光看不练假把式。

安装 (略)

node命令

我们在安装node之后,就可以直接在控制台开始操作了。

node -v 查看node的版本

而我们在cmd中也可以直接用node运行我们得代码,像下面这样:

	node 
	console.log('hello word!')

在这里插入图片描述
这样我就简单的看到了node展示出来的效果。
当然,除了这种简单的,我们还可以放一个函数在上面就像下面这样:
在这里插入图片描述
在这里插入图片描述
我们除了可以在直接在node里面运行代码,我们还可以用node运行文件。目前我只尝试过js文件。我在users\Administrator下面新建了一个server.js
内容如下
在这里插入图片描述然后使用

node server.js 运行该文件

在这里插入图片描述
我们在网页上打开http://127.0.0.1:8888可以看到页面上已经有了输出内容
在这里插入图片描述

REPL

REPL(交互式解释器),可以执行以下任务:

读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。

执行 - 执行输入的数据结构

打印 - 输出结果

循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。

即我们上面直接在node里面运行代码的实例;
直接运行node,然后在后面直接输入运行代码,我觉得这和浏览器控制台的效果是相同的(个人理解)。

node 

简单的表达式运算

>1+2
3
>5-4
1

变量操作

>var x=10
undefined
>y=11
11
>x+y
21
>console.log("hello word")
hello word
undefined

多行表达式
在这里插入图片描述
下划线(_)变量

>x=10;
10
>x+13
23
>_
23	

我们总结一下REPL命令
REPL 命令(引用node链接

ctrl + c - 退出当前终端。

ctrl + c 按下两次 - 退出 Node REPL。

ctrl + d - 退出 Node REPL.

向上/向下 键 - 查看输入的历史命令

tab 键 - 列出当前命令

.help - 列出使用命令

.break - 退出多行表达式

.clear - 退出多行表达式

.save filename - 保存当前的 Node REPL 会话到指定文件

.load filename - 载入当前 Node REPL 会话的文件内容。

回调函数

需要多看几遍

事件循环

需要再看几遍

Buffer(缓冲区)

需要在看几遍

stream流

关于文件的读取,在前端我在接触之前一个项目的时候,接触过文件流的传递,不然我一直会觉得文件的读取和前端的关系不大。关于文件的读写,学习之后觉得自己还是在前端缺太多了。
首先我们需要先了解在node中,stream有哪几种状态。
Readable-可读操作
Writable-可写操作
Duplex-可读可写操作
Transform-操作被写入数据,然后读出结果
由于Stream对象都是EventEmitter的实例。常用事件有:
data-当有数据可读时触发
end-没有更多的数据可读时触发
error-在接收和写入过程中发生错误时触发
finish-所有数据已被写入到底层系统时触发

读取文件内容代码:

var fs = require("fs");
var data=""; 
//创建可读流
var readStream=fs.createReadStream("input.txt");
readStream.setEncoding("UTF8");
readStream.on("data",function(str){
	data+=str;
});
readStream.on("end",function(){
	console.log(data);	
})
readStream.on("error",function(err){
	console.log(err.stack)	
});
console.log("程序执行完毕");

打印效果如下图:
在这里插入图片描述
可写入文件代码

var fs=require("fs");
var data = 'sfasfasfasfasffffffffffffffffffffffffffff';
var writeStream = fs.createWriteStream("output.txt");
writeStream.write(data,'UTF8');
writeStream.end();
writeStream.on("finish",function(){
	console.log("写入成功。")
})
console.log("程序执行完成。")

重新打开output.txt文件,可看到我们已经将内容写入成功。
在这里插入图片描述从一个文件读取内容复制到另外一个文件。现在我们知道input.txt和output.txt文件内容不同,现在我想要直接读input.txt的内容到output.txt文件中。

var fs = require("fs");
var readStream = fs.createReadStream('input.txt');
var writeStream = fs.createWriteStream('output.txt');
readStream.pipe(writeStream);//pipe是管道读写操作,直接读取readStream的内容写到writeStream文件中。
console.log("程序完成!!")

在这里插入图片描述
我们可以看出此时input.txt和output.txt文件内容已经完全相同。我们已经完成了文件内容的复制。
我们可以在上述情况下,做一个从input.txt文件复制内容,但是保留output.txt文件的原本内容。
在这里插入图片描述
我们先来看看连个文件的内容。

var data="";
var readStream = fs.createReadStream('input.txt');
var readStream1 = fs.createReadStream('output.txt');

readStream1.on("data",function(str){
	data+=str;
});
readStream.on("data",function(str){
	data+=str;
});
readStream.on("end",function(){
	var writeStream = fs.createWriteStream('output.txt');
	writeStream.write(data,"UTF8")
})
console.log('操作结束!')

执行这段代码之后,我们再来看看两个文件的内容
在这里插入图片描述
可以看到这这次的文件内容复制不是直接覆盖,而是将两个文件的内容整合在一起了。不过我觉得上面那个代码还有可优化的空间。不会是这么生硬的写法吧。
注意:fs.createWriteStream(‘output.txt’)之后,output.txt的文件内容就变成空了。

文件压缩

我们在上面了解到了管道流操作,可以读写文件。链式流是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。
下面我们简单的来压缩一个文件。

var fs =  require("fs");
var zlib = require("zlib");
fs.createReadStream('output.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('output.txt.gz'));
console.log("压缩成功!")

代码执行成功之后,我们就可以看到在output文件的旁边生成了一个output.txt的压缩包。
下面我们将原本的output.txt文件删除。然后对output.txt.giz文件进行解压

var zlib = require('zlib');
fs.createReadStream('output.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('output.txt'));
console.log("文件解压成功!")

这样我们就可以看到output.txt文件又出现啦,压缩,解压的过程就是如此soeasy。

模块系统

在node.js中提供了两个对象,exports 和require。exports 是模块公开暴露的接口。require则是在外部获取一个模块的接口,即获取模块的exports;
node.js里面存在4类模块(原生模块和3中文件模块)
图片引用于https://www.runoob.com/nodejs/nodejs-module-system.html从文件模块缓存中加载
我们可以看出各个模块加载的优先级略有不同。但是都会优先从文件模块的缓存中加载已经存在的模块。
从原生模块中加载
原生模块的优先级仅次于文件模块缓存的优先级。优先检查模块是否在原生模块列表中。原生模块也有一个缓存区,同样也是优先从缓存区加载,如果缓存区没有被加载过,则调用原生模块的加载方式进行加载和执行。
从文件加载
当文件模块缓存不存在,而且也不是原生模块的时候。node.js会解析require方法传入的参数。并从文件系统中加载实际的文件。
require方法接受以下几种参数的传递:

http、fs、path等,原生模块。
./mod或../mod,相对路径的文件模块。
/pathtomodule/mod,绝对路径的文件模块。
mod,非原生模块的文件模块。

node.js函数

在js中,我们可以定义一个函数作为另一个函数的参数。

路由

全局对象

还需要多看
node.js的全局对象是global,所有变量(除了global本身之外),都是global对象的属性。我们在node.js中能能够直接访问到的对象通常都是global的属性,如console,process等,下面会继续介绍。
全局变量与全局对象
global最根本的作用是作为全局变量的宿主。按照ECMAScript的定义,全局变量需满足下面条件;

  • 在最外层定义的变量;
  • 全局对象属性;
  • 隐式定义的变量。
    当你定义一个全局变量时,这个变量同时也会成为全局对象的属性。

注意:应当永远使用var定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。

process是一个全局对象,即global对象的属性。
它是用于描述当前node.js进程状态的对象,提供了一个与操作系统的简单接口。
node.js全局对象

常用工具-util

util.inherits()是一个实现对象间原型继承的函数。
util.inherits(constructor,superConstructor);

文件系统

node导入文件系统模块(fs)语法:

var fs =  require("fs");

同步和异步读取文件。

node.js文件系统米块中的方法均有同步和异步的版本,例如读取文件内容的函数就有异步fs.readFileSync()和同步fs.readFile();
异步方法函数的最后一个参数为回调函数,回调函数的第一个参数包含了错误信息。建议使用异步方法。性能高效,速度快,无阻塞。

var fs = require("fs");
//异步读取效果
fs.readFile("input.text",function(err,data){
	if(err){
		console.log(err)
		};
		console.log("异步读取:"+data.toString())
	})
	//同步读取
	var data=fs.readFile("output.txt");
	console.log("同步读取:"+data.toString());
	console.log("程序执行完毕")
}

我们可以看到同步获取的数据是在程序执行完之前的读取完毕的,而异步的读取结果却是在程序执行完之后才执行的。
在这里插入图片描述
由于之前进行的管道赋值操作,我的input.txt和output.txt的文件内容是一样。
我们可以看出异步和同步的执行顺序的不同

打开文件

open(不过这个打开文件和我想象中的不太一样,我以为可以直接打开文件,像下面这样)
在这里插入图片描述
(结果和我想象中有些出入,它是这样的)
在这里插入图片描述
嗯?好吧,可能确实是我想太多。
我们用node.js打开文件,代码如下:

var fs = require("fs");
console.log("准备打开文件")
fs.open('input.txt','rs',function(err,fd){
	console.log(fd);
	console.log("打开文件")	
})

下面我们来了解一下open的参数(此地参考菜鸟教程):

fs.open(path, flags[, mode], callback)
  • path:是指文件路径
  • flags:是指打开文件的方式
  • mode : 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
  • callback:回调函数,带有两个参数如:callback(err, fd)。

flags的参数值可以是以下值:

Flag描述
r以读取模式打开文件。如果文件不存在抛出异常
r+以读写模式打开文件。如果文件不存在抛出异常。
rs以同步的方式读取文件。
rs+以同步的方式读取和写入文件。
w以写入模式打开文件,如果文件不存在则创建。
wx类似 ‘w’,但是如果文件路径存在,则文件写入失败。
w+以读写模式打开文件,如果文件不存在则创建。
wx+类似 ‘w+’, 但是如果文件路径存在,则文件读写失败。
a以追加模式打开文件,如果文件不存在则创建。
ax类似 ‘a’, 但是如果文件路径存在,则文件追加失败。
a+以读取追加模式打开文件,如果文件不存在则创建。
ax+类似 ‘a+’, 但是如果文件路径存在,则文件读取追加失败。

获取文件信息

fs.stat(path,callback);
  • path是文本路径

  • callback是回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。

      var fs = require("fs");
      fs.stat('input.txt',function(err,stats){
      	console.log(stats);
      })
    

在这里插入图片描述
我们可以获取这部分文件的数据。
当然我们也可以通过stat提供的方法判断文件的一些属性(参考菜鸟教程):

方法描述
stats.isFile()如果是文件返回 true,否则返回 false。
stats.isDirectory()如果是目录返回 true,否则返回 false。
stats.isBlockDevice()如果是块设备返回 true,否则返回 false。
stats.isCharacterDevice()如果是字符设备返回 true,否则返回 false。
stats.isSymbolicLink()如果是软链接返回 true,否则返回 false。
stats.isFIFO()如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。
stats.isSocket()如果是 Socket 返回 true,否则返回 false。

写入文件

fs.writeFile(file,data[,options],callback)

参数说明

  • file:文件名或文件描述符

  • data:要写入文件的数据,可以是string字符串或buffer缓冲对象。

  • options:该参数是一个对象,包含{encoding,mode,flag}。默认编码为utf8,模式为0666,flag为‘w’(该模式下直接覆盖源文件内容)

  • callback:回调函数,回调函数只包含错误信息参数(err),在写入失败时调用。

      fs.writeFile('input.txt','一二三四一二三四想收个,老板、是色均有绿色均有教会我',function(err){
      	if(err){
      		return console.err(err);
      	}
      })
    

在这里插入图片描述
此时我们已经替换了input.txt中的内容。

读取文件

fs.read(fd,buffer,offset,length,psition,callback)

该方法使用了文件描述符来读取文件
参数使用如下(参考菜鸟教程):

  • fd:通过fs.open()方法来返回文件描述符

  • buffer:数据写入的缓冲区

  • offset:缓冲区写入的写入偏移量

  • length:要冲文件中读取的字节数

  • position:文件读取的起始位置,如果position的位置为null,则会从当前文件指针的位置读取。

  • callback:回调函数,有三个参数err,bytesRead,buffer,err为作为信息,bytesRead表示读取的字节数,buffer为缓冲区对象。

      var buf = new Buffer.alloc(1024);
      console.log("准备打开文件");
      fs.open("input.txt","r",function(err,fd){
      	if(err){
      		return console.err(err);		
      	}
      	console.log("打开文件。");
      	console.log("准备读取文件");
      	fs.read(fd,buf,0,buf.length,0,function(err,btyes){
      		console.log("读取文件内容")
      		if(err){
      			return console.err(err)
      		};
      		console.log(btyes+"个字节被读取");
      		if(btyes>0){
      			console.log(buf.slice(0).toString())
      		}
      	})
      })
      console.log("程序执行结束。")
    

在这里插入图片描述
我们就顺利的通过了fs.read方法读取了文件内容。

关闭文件

fs.close(fd,callback)

参数说明

  • fd:fs.open()方法返回的文件描述
  • callback:回调函数,没有参数,可返回err错误提示

截取文件

fs.fteuncate(fd,len,callback);//该方法使用了文件描述符来读取文件

参数使用说明:

  • fd:通过fs.open()方法返回的文件描述符
  • len:文件内容截取长度
  • callback:回调函数,没有带参数
    其实我们前面了解到的read也可以只读取一部分文件内容。fs.read(fd,buffer,offset,length,psition,callback)控制length长度就可以只读取文件的一部分

删除文件

fs.unlink(path,callback)

参数说明:

  • path:文件路径
  • callback:回调函数,没有参数

创建目录

fs.mkdir(path[,options],callback)

参数说明:

  • path:文件路径

  • options:参数可以是:

    • recursive:是否以递归的方式创建目录,默认为false。
    • mode:设置目录权限,默认为 0777。
  • callback:回调函数,没有参数

     fs.mkdir('newObject/',function(err){
     	if(err){
     		return console.err(err);
     	}
     	console.log("创建目录成功");
     })
    

在这里插入图片描述
我们可以看到newObject文件夹就创建成功了,说明目录创建成功。当我们创建已存在的目录时,就会出现报错
在这里插入图片描述

读取目录

fs.readir(path,callback)

参数说明:

  • path:文件路径
  • callback:回调函数,回调函数带有err,files。err为错误信息,files为目录下的文件数组列表

我们在刚刚新建的newObject里面新增一些内容。
在这里插入图片描述
然后执行下面代码;

fs.readdir("newObject/",function(err,files){
		if(err){
				console.log(err)
			}
			console.log(files);
	})

我们可以得到如下结果
在这里插入图片描述
证明确实拿到了所查询目录下的所有文件。

删除目录

fs.rmdir(path,callback);

参数说明:

  • path:文件路径
  • callback:回调函数,没有参数

除了我们上面介绍到的模块方法,我们还有其他文件的模块方法。在这里直接引用菜鸟教程的模块方法参考手册
文件模块方法参考手册。进入链接之后可直接f3查询 文件模块方法参考手册 以方便直接定位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值