even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、Event事件模块

  介绍: 事件是整个node.js的核心, node.js中大部份模块都使用或继承了该模块(类似WebAPI中的EventTarget)

  使用: require('events')  引入该模块

入门案例

const eventEmit = require('events')

class Report extends eventEmit {  //继承事件系统
    constructor(message) {
        super()
        this.msg = message
    }

    init() {
        this.on('get', this.msgFlect)    //订阅事件
    }

    msgFlect() {
        console.log(this.msg, arguments)
    }
}

let r = new Report('are you ok???');
r.init();

r.emit('get', 'this is test') //触发事件

 EventEmitter.defaultMaxListeners 

表示默认的监听器的个数,可以通过  EventEmitter.getMaxListeners()来获取最大的监听器个数,默认是10个,EventEmitter.setMaxListeners来设置最大的监听器个数

//在断续上段代码的前提下

r.setMaxListeners(100)
console.log(r.getMaxListeners()) //输出100

emitter.addListener(eventName, listener)

emitter.on的别名,表示监听指定的函数

emitter.eventNames()

表示获取当前事件的所有名称

emitter.once(eventName, listener)

 表示只触发一次便从监听事件的队列中移除, 也就是只会触发一次

r.once('check', () => {
    console.log('this is checkEvent')
})

r.emit('get', 'this is test') //触发事件

console.log(r.eventNames()) // 输出 [ 'get', 'check' ]

r.emit('check')

console.log(r.eventNames()) //输出 [ 'get' ]

emitter.listenerCount(eventName)

表示获取指定名称的监听的数量值

console.log(r.listenerCount('get')) //输出 1

emitter.off(eventName, listener)

取消指定的事件监听

emitter.prependListener(eventName, listener)

向前追加事件的监听

emitter.prependOnceListener(eventName, listener)

向前追加一次性触发后即被移除的事件

emitter.removeAllListeners([eventName])

移除全部监听器或指定的 eventName 事件的监听器。

emitter.removeListener(eventName, listener)

从名为 eventName 的事件的监听器数组中移除指定的 listener

 

2、process进程对象

  介绍 :process对象是一个全局变量,它提供当前Node.js进程的有信息,以及控制当前node.js进程

  使用:全局对象, 不需要require

  常用api:  

    .argv  用来获取当前运行node程序的相关参数

    .env  用来获取当前的环境变量

    .exit()  用来中止当前进程

    .stdout  标准输出流   .write(data[, encoding][, callback])

    .stdin  标准输入流, 系统默认监听'data'这个事件

process.stdout.write('this is text');        //输出this is text
    
process.stdin.on('data', (e) => {            //用户输入完成后回车后会触发对应的函数 
    console.log("用户输入了", e, e.toString())
})

 

3、stream 流

  介绍:流是一种在node.js中处理流式数据的抽象接口, stream模块提供了一些基础的API, 用于构建实现了流接口的对象, Node.js中许多的对象都是提供了流的实现, fs文件操作, net, dgram, http,https等

  使用:require('stream')

  流的基本类型:

    Writable - 可写入数据的流(例如:  fs.createWriteStream())   

    Readable - 可读取数据的流(例如: fs.createReadStream()) 

    Duplex - 可读又可写的流( net.Socket) 

    Transform - 在读写过程中修改或转换数据的Duplex流(如: zlib.createDeflate())

  注意:这里只规定了些特性,具体是由对应的模块来实现的,如果 fs http等

 

4、Buffer 

  介绍: 用于操作二进制数据的类

  特点:类似数组    长度固定  只能操作二进制数据

  使用:Buffer 类在 Node.js 中是一个全局变量,因此无需使用 require

    常用api

  

let bf = Buffer.alloc(4, 'bill')
console.log(bf)   //转化后会输出bill对应的16进制码的二进制流

let bf1= Buffer.alloc(6, '你好')
console.log(bf1)

//不同的编码中文的长度是不一致的,在utf8下,一个中文占3个字符


let bf2 = Buffer.from('are you ok???', 'utf8')
console.log(bf2)


let bf3 = Buffer.from([1,2,3,4,5])
console.log(bf3)

 

 buffer的静态方法

5、FileSystem

  介绍:fs模块提供了一些与文件系统进行交互的API

  使用:require('fs')

  实现数据的CURD

const fs = require('fs')
//异步的写入文件的方法,如果不存在对应的文件,则会创建文件
//如果当前目录不存在就会创建不成功
fs.writeFile('test.txt', 'are you ok???', err => {
    if(err)  throw err
    console.log('保存成功')
})

注意: First Error:  node中一种约定,如果一个回调可能有错误发生,函数的第一个参数专门用来存在错误的

fs.writeFileSync同步的写文件方法,如果错误,那么错误由try...catch来捕获

const fs = require('fs')

try{
    fs.writeFileSync('./aaa/test.txt', 'are you ok???')
}catch(err) {
    console.log(err)
}

 追加内容的方式

const fs = require('fs')

//异步的追加内容
fs.appendFile('./test.txt', '\nthis is second', err => {
    if(err) throw err;
    console.log('写入成功')
})


//同步的方式追加内容
try{
    fs.appendFileSync('./aaa/test.txt', 'wrong')
}catch(err) {
    throw err
}

 操作文件的其他方法

const fs = require('fs')

//读取文件
fs.readFile('./test.txt', (err, data) => {
    if(err) return 
    console.log(data)
})

//读取文件的其他信息
fs.stat('./test.txt', (err, data) => {
    console.log(err, data)
    //判断是否是文件
    console.log(data.isFile())
})

//同步的方式
let handle = fs.statSync('./test.txt')
console.log(handle)
console.log(handle.isFile)

//删除文件夹
// fs.unlink('./aa', err => {
//     console.log(err)
// })

//创建文件夹,加上配置可以创建多重文件夹
fs.mkdir('./a/b/c', { recursive: true }, err => {
    console.log(err)
})

 封装一个文件以及文件夹拷贝和删除的方法

const fs = require('fs')
const path = require('path')

let manage = (function() {
    const isDir = (dirent) => {   //参数是fs.Dirent对象或者路径
        if(dirent instanceof fs.Dirent) return dirent.isDirectory();
        return fs.statSync(dirent).isDirectory()
    }

    const removeFile = (path) => {    //对删除文件进行二次封装
        try{
            fs.unlinkSync(path)
        }catch(err) {
            console.log(err)
        }
    }

    const dealWithFile = (list, p) => {
        list.forEach(val => {
            let dirPath = path.join(p, val.name)
            if(isDir(val)) {                //如果是文件夹的情况
                removeReadpath(dirPath)            //如果是文件夹,那么就进行递归调用删除
                return
            }
            removeFile(dirPath)            //删除文件
        })
        fs.rmdirSync(p)                    //删除最外层的文件夹
    }

    const removeReadpath = path => {
        try{
            let list = fs.readdirSync(path, { withFileTypes: true })    //注意配置,如果没有配置返回的是Array<String>
            dealWithFile(list, path)
        }catch(err) {
            console.log(err)
        }
        
    }

    const copyFile = (filePath, target) => {    //进行文件拷贝
        try{
            let fileName = path.basename(filePath)
            let targetName = path.join(target, fileName)
            fs.copyFileSync(filePath, targetName,  fs.constants.COPYFILE_EXCL)
        }catch(err) {
            console.log(err)
        }
    }


    const copyDealWithFile = (list, fpath, target) => {
        list.forEach(val => {
            let source = path.join(fpath, val.name)
            if(!isDir(val)) {    //如果是文件的情况下,就直接拷贝
                copyFile(source, target)
            } else {
                let newTarget = path.join(target, val.name)
                !fs.existsSync(newTarget) && fs.mkdirSync(newTarget)
                copyDir(source, newTarget)
            }
        })
    }

    const copyDir = (filepath, target) => {
        try{
            let list = fs.readdirSync(filepath, { withFileTypes: true })
            copyDealWithFile(list, filepath, target)
        }catch(err) {
            console.log(err)
        }
    }

    return {
        removeFile(path) {        //递归的方式删除文件夹或文件
            if(!fs.existsSync(path)) {
                console.log('指定的文件不存在')
                return
            }
            isDir(path)? removeReadpath(path): removeFile(path)
        },
        copyFile(filePath, target){    //进行文件拷贝的方法
            !fs.existsSync(target) && fs.mkdirSync(target, { recursive: true })    //如果不存在,那么就创建新的文件夹
            if(!isDir(filePath)) {        //如果是文件
                copyFile(filePath, target)
                return
            }
            copyDir(filePath, target)
        }
    }
})()

manage.removeFile('./e')

 文件或目录的监听函数

const fs = require('fs')
const path = require('path')

//监听文件
// fs.watchFile('./check.txt', (curr, prev) => {
//     console.log(curr)
//     console.log(prev)  //注意这里输出的是Stat对象
// })

//监听文件或目录
//注意这里的recursive是指深层次监听子目录
fs.watch('./a', { recursive: true }, (type, filename) => {
    console.log(type, filename)    //type 是 'rename' 或 'change', filename 是触发事件的文件的名称。
})

 注意: fs.read(fd, [options,] callback), 这里的fd是表示类似fs.open后获取的文件句柄,fs.openSync(path, 'w+')可以用于创建空文件

 6、fs文件系统的promise对象使用

API 可通过 require('fs').promises 或 require('fs/promises')

posted on 2021-02-07 12:59  even_blogs  阅读(125)  评论(0编辑  收藏  举报