node 内置模块,node.js常用模块

  node 内置模块,node.js常用模块

  本文带你了解Nodejs中常见的内置模块(路径、文件系统、事件)。希望对你有帮助!

  node.js速度课程简介:进入学习

  

内置模块path

  路径的演练

  路径模块用于处理路径和文件,并提供了许多有用的方法。

  我们知道Mac OS、Linux和windows上的路径分隔符是不同的。

  在Mac OS和Linux的Unix操作系统上,使用/作为文件路径的分隔符。windows将使用``或\作为文件路径的分隔符。当然,目前也支持/。那么如果我们在windows上开发一个使用\作为分隔符的应用程序,我们应该怎么做才能把它部署到Linux上呢?

  路径的显示会有一些问题,所以为了屏蔽它们之间的差异,我们可以在开发中使用路径模块进行路径的操作。如果我们盲目拼接两条路径,比如path1 / path2,可能在当前操作系统下运行,但是如果我们换个操作系统来执行代码,可能就认不出路径了,因为不同的操作系统需要不同的路径分割器。

  const path=require(path )

  //我们故意在path1和path2的路径中写错了分隔符。

  const path1=User\ASUS\DCC

  Constpath2=我的工作\ 5月4日

  //path对象中的resolve方法可以根据当前操作系统选择正确的路径分隔符,实现两条路径的拼接。

  const fileName=path . resolve(path 1,path2)

  //大家可以看到我们原来的字符串本来是用\拼接的,但是在传递了path.resolve方法之后,就用\拼接了。

  console.log(文件名);//C:\Users\ASUS\Desktop\前端学习\算法\ user \ ASUS \ DCC \ my work \path模块的其他方法年5月4日

  1. 获取路径的信息

  path.dirname()方法返回路径的目录名。path.basename()方法返回路径的最后一部分。一般来说,文件名path.extname()方法返回扩展名const path=require(path )

  const file=/foo/bar/baz/asdf/quux . html

  const path1=path.dirname(文件)

  const path2=path.basename(file)

  const path3=path.extname(file)

  console . log(path 1);///foo/bar/baz/asdf

  console . log(path 2);//quux.html

  console . log(path 3);//.html2. join路径拼接

  path.join()方法使用特定于平台的分隔符将所有给定的路径片段连接在一起,并规范化生成的路径。简单来说,就是根据当前操作系统选择合适的路径分隔符将多条路径拼接在一起。当然,它也会纠正原路径中不正确的分隔符。

  const path=require(path )

  const path1=/USER/ASUS

  const path2=My/DCC

  const fileName=path.join(path1,path2)

  console.log(文件名);//\USER\ASUS\My\DCC3. resolve方法拼接(用的最多)

  path.resolve()方法将一系列路径或路径段解析为绝对路径。

  const path=require(path )

  const path1=asd/sad

  const path2=My/DCC

  const fileName1=path.join(path1,path2)

  const filename 2=path . resolve(path 1,path2)

  console.log(文件名1);//asd\sad\My\DCC

  console.log(文件名2);//C:\Users\ASUS\Desktop\前端学习\算法\asd\sad\My\DCC4. resolve和join方法的区别

  如果在处理完所有给定的路径片段后还没有生成绝对路径,将使用当前的工作目录,并且它可以识别./,/和/path.resolve (wwwroot , static _ files/png/,./gif/image . gif );

  //如果当前工作目录是/home/my/node,

  //然后返回“/home/my/node/wwwroot/static _ files/gif/image . gif”。从右到左处理给定路径的序列,依次解析每个路径,直到构造出一个绝对路径const path=require(path )。

  const path1=asd/sad

  const path2=/My/DCC

  const fileName1=path.join(path1,path2)

  const filename 2=path . resolve(path 1,path2)

  console.log(文件名1);//asd\sad\My\DCC

  console.log(文件名2);//\ My \ DCC生成的路径被规范化,末尾的斜杠将被删除,除非该路径被解析为根目录const path=require(path )

  const path1=/USER/ASUS

  const path2=My/DCC/

  path.join(path1,path2) //\USER\ASUS\My\DCC\

  path.resolve(path1,path 2)//\ USER \ ASUS \ My \ DCCpath.resolve方法在webpack中也有大量使用

  例如,当我们在react项目中使用craco配置路径别名时。

  使用ES Module也是可以引入node中的核心模块的

  如上所述,ES模块是允许导入CommonJS的模块的,那么自然,你也可以导入node中嵌入的核心模块。

  //test.mjs

  从“路径”导入路径

  console.log(路径);//是正常路径对象

内置模块fs

   fs是文件系统的缩写,表示文件系统。

  任何服务于服务器端的语言或框架通常都有自己的文件系统。

  因为服务器需要把各种数据和文件放在不同的地方,比如大部分用户数据可能放在数据库里,比如一些配置文件或者用户资源(图片、音频、视频)在操作系统上是以文件的形式存在的。节点也有自己的文件系统操作模块,即fs。

  借助Node封装的文件系统,我们可以在任何操作系统(windows、Mac OS、Linux)上直接操作文件。这也是Node能开发服务器的一大原因,它能成为前端自动化脚本等流行工具。fs的API介绍

  大多数API提供三种操作模式:

  方法一:同步操作文件——的代码会被阻塞,const fs=require(fs )不会继续执行。

  常量文件名=。/test.html

  const file=fs.statSync(文件名)

  console.log(文件);statSync方法可以同步读取我们的文件信息,并返回一个fs实例。统计数据

  方法二:异步回调函数操作文件3354的代码不会被阻塞,需要传入回调函数。当获得结果时,将执行回调函数。如何使用fs.stat(path,callback),回调有两个参数(err,stats),异步读取文件,我们的回调函数会在出错或者读取完成后执行。

  const fs=require(fs )

  常量文件名=。/test.html

  //回调函数的两个参数,一个是错误信息,一个是文件信息。

  const file=fs.stat(文件名,(错误,信息)={

  console . log(info);//统计类

  })

  console.log(文件);//undefined,因为是异步的,所以不会阻塞代码执行。打印时,尚未获取文件信息。方法三:异步承诺操作文件3354代码不会被阻塞。通过fs调用方法操作。承诺会返回一个承诺,可以通过then和catch进行处理。

  许多API都提供了promise,但不是全部,所以在使用某些东西时,可以先查阅文档const fs=require(fs )。

  常量文件名=。/test.html

  //fs.promise是fs模块中的一个对象,里面的很多方法都是基于promise的。

  const file=fs.promises.stat(文件名)。然后(res={

  console . log(RES);//状态类

  }).catch(错误={

  console . log(err);

  })

  console.log(文件);//承诺{待定}文件描述符

  什么是文件描述符?

  在POSIX系统上,对于每个进程,内核维护一个当前打开的文件和资源的列表。每个打开的文件被分配一个简单的数字标识符,称为文件描述符。在系统级,所有文件系统操作都使用这些文本描述符来识别和跟踪每个特定的文件。Windows系统使用不同但概念相似的机制来跟踪资源。为了简化用户的工作,Node.js抽象出操作系统之间的具体差异,并为所有打开的文件分配一个数字文件。也就是说,node中的很多API都把文本描述符屏蔽掉了,相当于在内部替你做了这些操作。

  fs.open()方法用于分配一个新的文件描述符。一旦赋值,文件描述符就可以用来从文件中读取数据,向文件中写入数据,或者请求有关文件const fs=require(fs )的信息。

  常量文件名=。/test.html

  fs.open(文件名,(错误,fd)={

  console . log(FD);//4

  //通过描述符读取相应的文件信息

  fs.fstat(fd,(err,info)={

  console . log(info);//Stats对象

  })

  })文件的读写

  如果我们离线对文件的内容进行操作,此时就可以读写文件了。

  Fs.readfile (path,options,callback):读取文件的内容fs.wraitefile (file,data,options,callback):在文件中写入内容1. 文件写入

  const fs=require(fs )

  Fs.writeFile(。/a.txt ,你好!,错误={

  console . log(err);

  })我们本来没有这个文件,但是由于options参数中的flag属性默认为W,所以它会帮助我们自动创建一个文件,并将相应的值写入其中。

  在上面的代码中,你会发现有一个花括号,里面什么也没填。这是写的时候填写的选项参数。

  Flag:书写方式,默认为‘W’

  r -以读取模式打开文件。如果文件不存在,将出现异常“r”——以读写模式打开文件。如果文件不存在,将出现异常“RS”——以同步读写模式打开文件。命令操作系统绕过本地文件系统缓存“w”-以写模式打开文件。文件将被创建(如果文件不存在)或截断(如果文件存在) wx -类似于 w ,但如果路径存在,它将失败 w -以读写模式打开文件。文件将被创建(如果文件不存在)或截断(如果文件存在)。wx -类似于 w ,但如果路径存在则失败 a -以追加模式打开文件。如果文件不存在,它将被创建为“ax”-类似于“a”,但如果路径存在,它将失败“a”-以读取和附加模式打开文件。如果文件不存在,它将被创建为 ax --类似于 a ,但是如果路径存在,它将失败const fs=require(fs )

  Fs.writeFile(。/a.txt ,你好!,{ flag: a },err={

  console . log(err);

  })在我们将flag改为A之后,我们所做的是追加文件,发现我们要写的文本出现在目标文件的末尾。

  编码:字符的编码,默认为 utf82. 文件读取

  读取文件时,如果不填写编码,返回的结果是Buffer,类似于一串二进制代码。

  因为在fs.readFile方法中,encoding属性的默认值是null,也就是说它没有默认值,需要我们手动指定。其标志的默认值是“r”

  const fs=require(fs )

  //没有指定编码,他不知道用哪种字符编码格式读取文件。

  fs.readFile(。/a.txt ,(err,data)={

  console.log(数据);//Buffer E4 BD A0 E5 a5 BD E5 95 8a ef BC 81 E4 BD A0 E5 a5 BD E5 95 8a ef BC 81 E4 BD A0 E5 a5 BD E5 95 8a ef BC 81

  })

  fs.readFile(。/a.txt ,{encoding: utf-8},(err,data)={

  console.log(数据);//你好!你好!你好!

  })文件夹操作

  1. 新建一个文件夹 — fs.mkdir(path[, mode], callback)

  const fs=require(fs )

  const path=require(path )

  //绝对路径

  const targetDir=path . resolve(_ _ dirname, dcc )

  尝试{

  fs.mkdirSync(目标目录)

  } catch (err) {

  console . log(err);

  }

  //相对路径

  const dirname=。/dcc

  //fs模块有一个existsSync方法来确定当前参数对应的路径是否存在。

  如果(!fs.existsSync(目录名)){

  fs.mkdir(目录名,错误={

  console . log(err);

  })

  }发现已经创建了对应的文件夹。如果我们再次执行这个程序,我们将报告一个错误,这个错误显示不能重复创建同一个文件夹。同时也说明了我们在使用fs.mkdir方法创建文件时,可以传入绝对路径或者相对路径。

  2. 获取文件夹的所有文件 — fs.readdir(path[, options], callback)

  const fs=require(fs )

  fs.readdir(。/dcc ,(错误,文件)={

  //它读取的是一个文件数组,包括里面的目录。

  console.log(文件);//[ a.html , b.txt , c.md ,dir ]

  })思考:如果我们现在要把这个文件夹里的所有文件都读出来,比如这个文件夹里其他文件夹里的文件,我们该怎么办?

  实际上,readdir方法在以传入参数的形式读取目录下的文件时,也可以传出其对应的文件类型,即把options对应的withFileTypes属性改为true。

  然后每个文件信息对应一个Dirent对象,每个对象都有一个isDirectory方法(在原型上)来判断当前文件是否是文件夹,如下图所示:

  由于文件夹中可能有文件夹,所以需要用递归的方法读出所有文件的路径。

  const fs=require(fs )

  const path=require(path )

  const getFileName=(目录名)={

  //根据路径读取目录路径下的所有文件名,

  //withFileTypes属性更改为true,以在读取文件名时公开文件类型。

  //文件类型不是Dirent对象下的属性,但是我们需要通过isDirectory方法获取。

  fs.readdir(dirname,{ withFileTypes: true },(err,files)={

  files.forEach(file={

  //每个目录对象都有一个isDirectory方法来确定文件是否是文件夹。

  if (file.isDirectory()) {

  //如果当前文件还是一个文件夹,需要通过resolve方法找到它的路径,然后递归调用函数。

  const file path=path . resolve(dirname,file.name)

  获取文件名(文件路径)

  //如果不是文件夹就直接打印名字。

  }否则{

  console . log(file . name);

  }

  })

  })

  }

  GetFileName(。/DCC’)从打印结果可以知道,已经递归实现了打印一个目录下的所有文件名。

  3. 文件夹重命名

  也许重命名操作需要以管理员身份运行编辑器才能被允许。

  const fs=require(fs )

  fs.rename(。/dcc“,”。/kobe ,err={

  console . log(err);

  })文件夹的复制案例

  场景:一个文件夹里有很多文件夹,每个文件夹里有很多文件。现在,需要根据原始文件目录格式将这些文件复制到另一个文件夹中。

  const fs=require(fs )

  const path=require(path )

  //获取起始文件路径和目标文件路径

  const startPath=process.argv[2]

  const endPath=process.argv[3]

  const ext=process.argv[4] 。js

  //获取起始路径下的文件

  const all dirs=fs . readdirsync(start path)

  //遍历其文件夹并取出其子文件夹

  for(所有目录的常量名称){

  //原始文件夹的路径

  const origin dir=path . resolve(start path,name)

  //获取过去副本的文件夹路径。

  const target dirname=path . resolve(end path,name)

  //通过判断该路径是否存在来决定是否新建文件夹。如果存在,则意味着该文件已经被创建。只需跳过并创建下一个文件夹。

  if (fs.existsSync(targetDirname))继续;

  //在目标路径下新建一个文件夹

  fs.mkdirSync(目标目录名)

  //读取与之对应的文件夹中的文件

  const currDirFiles=fs . readdirsync(originDir)

  //遍历文件夹以获取所有文件

  for(curr dir files的常量名){

  //确定当前文件的后缀是否是复制过去的文件。

  if (path.extname(name)===ext) {

  //拼接得到原文件路径和复制的文件路径。

  const origin copy Name=path . resolve(origin dir,name)

  const target copy Name=path . resolve(target dirname,name)

  //copyFileSync方法用于复制文件,该方法接收两个参数,一个是要复制的源文件的名称,一个是复制操作的目标文件名。

  fs.copyFileSync(originCopyName,targetCopyName)

  Console.log(复制成功!);

  }

  }

  }当我们执行命令node test.js时。/dir1。/dir2。txt,我们发现所有带txt后缀的文件都被复制了,说明我们的程序没有问题。

  

Events模块

  events基础方法

  Node中的核心API由异步事件驱动。

  在这个系统中,你的一些对象(发射器)发出一个事件,我们可以监听它(监听器),事件触发时会调用传入的回调函数。发送事件和监听事件都是通过EventEmitter类完成的,它们都属于events对象。

  Emitter.on(eventName,listener):监听事件,或者使用AddListener Emitter。Off (eventname,listener):删除监听事件,或者使用RemoveListener发射器(eventname [,args]):发出事件,可以携带一些参数。我们从Events模块导入的内容不同于其他模块,因为我们可以基于这个类创建一个“transmitter”。

  const emitter emitter=require( events )

  console . log(emitter emitter);

  Const emitter=new EmitterEmitter()通过发射器,我们可以监控、取消和传输相应的事件。

  您可以同时监视多个相同的事件,所有绑定的函数都将被执行。启动事件时,可以携带多个参数。在监听的回调函数中,我们可以使用.余数运算符将它们集中到一个变量中。如果所有绑定的事件都相同,触发器将按照监控的顺序执行。下面的代码是先执行“我被点击了1”,再执行“我被点击了2”。//AddEvent Listener是on的简称。

  emitter.on(点击,(.args)={

  Console.log(我被点击了1 ,args);//2s后输出:我被点击了1 [科比,詹姆斯]

  })

  //如果所有事件都绑定到同一个事件,则触发器将按照监控的顺序执行。

  emitter.on(点击,(.args)={

  Console.log(我被点击了2 ,args);////2s后期输出:我被点了2 [科比,詹姆斯]

  })

  setTimeout(()={

  Emitter.emit (click , Kobe , James )//发起一个事件,可以带参数。

  },2000)如果我们重写setTimeout中的函数,然后拉出第二个注册事件的回调函数,打印出来的结果会怎样?

  //addEventListener是on的缩写

  emitter.on(点击,(.args)={

  Console.log(我被点击了1 ,args);

  })

  const clickFn=(.args)={

  Console.log(我被点击了2 ,args);

  }

  emitter.on(click ,clickFn)

  setTimeout(()={

  emitter.emit(click , kobe , james )

  emitter.off(点击,点击Fn)

  emitter.emit(click , kobe , james )

  },2000)当我们第一次发起一个事件时,两个注册的事件都会被触发,但是当我们用emitter.off取消第二个注册的事件时,下一次发起同一个事件时,第二个事件不会再被触发。

  events获取信息

  Emitter.eventNames(eventName)返回一个数组,该数组列出了触发器的注册侦听器的事件。

  Emi.listener count (eventName)返回正在侦听名为eventName的事件的侦听器数量。

  Emitter.listeners(eventName)返回名为eventName的事件的侦听器数组的副本。

  const emitter emitter=require( events )

  常量发射器=新发射器()

  emitter.on(点击,(.args)={

  Console.log(我被点击了1 ,args);

  })

  const clickFn=(.args)={

  Console.log(我被点击了2 ,args);

  }

  emitter.on(click ,clickFn)

  emitter.on(tab ,clickFn)

  console . log(emitter . event names());//[ click , tab ]

  console . log(emitter . listener count( click ));//2

  console . log(emitter . listeners( click ));//[[函数(匿名)],[函数:clickFn] ]events中不常用方法

  绑定到emitter.once的事件只被监听一次。向名为eventName的事件添加一个侦听器函数。下次触发eventName事件时,将删除侦听器,然后再次调用它。

  const emitter emitter=require( events )

  常量发射器=新发射器()

  emitter.once(click ,(.args)={

  Console.log(我被点击了1 ,args);

  })

  setTimeout(()={

  //这个事件的启动会执行emitter.once绑定的函数

  emitter.emit(click , kobe , james )

  //第二个事件的启动不会执行emitter.once绑定的函数

  emitter.emit(click , kobe , james )

  },500)emitter.prependListener将监听事件添加到前面,但是将监听器函数添加到名为eventName的事件的监听器数组的开头。不检查是否添加了侦听器。多次调用和传入同一个eventName和侦听器会导致侦听器被添加和调用多次。

  const emitter emitter=require( events )

  常量发射器=新发射器()

  emitter.on(点击,(.args)={

  Console.log(我被点击了1 ,args);

  })

  //由prepend listener方法绑定的函数将比由on绑定的回调函数更早执行。

  emitter.prependListener(click ,(.args)={

  Console.log(我被点击了2 ,args);

  })

  setTimeout(()={

  emitter.emit(click , kobe , james )

  },500) Mitter。将监听事件添加到前面,但只监听一次。

  Emi。removeall listeners ([eventName])删除eventName的所有或指定侦听器;注意,删除代码中其他地方添加的侦听器是一种不好的做法,尤其是当EventEmitter实例是由其他组件或模块(如socket或file stream)创建的时候。

  更多关于node的信息,请访问:nodejs教程!以上是对Node.js中常见内置模块细节的深入分析请多关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: