• nodejs 学习笔记(三)—— fs模块&Stream


    fs模块用来处理对文件的相关操作,常用的方法有:

    fs.stat —— 检测是文件还是目录

    fs.mkdir —— 创建目录

    fs.writeFile —— 写入文件(没有会新建,有会覆盖原来的)

    fs.appendFile —— 追加文件

    fs.readFile —— 读取文件

    fs.readdir —— 读取目录下所有文件和目录

    fs.rename —— 重命名文件/目录(还可以用来移动文件/目录)

    fs.rmdir —— 删除目录(目录要为空)

    fs.unlink —— 删除文件

    上面的这些方法大都是异步的,直接使用会遇到一些问题。比如这样一个例子:

    读取 test 目录下的所有文件,放进一个数组里:

    一般会想到要这样写:

    const path = './test'
    let files = []
    fs.readdir(path, (err, data) => {
        if (err) {
            console.log(err)
            return
        }
        for (var i = 0; i < data.length; i++) {
            fs.stat(path + '/' + data[i], (err, stats) => {
                if (err) {
                    console.log(err)
                    return
                }
                // 判断是不是文件,是文件放入数组中
                if (stats.isFile()) {
                    files.push(data[i])
                }
            })
        }
        console.log(files) // []
    })

    因为 fs.stat() 方法是异步的,在判断是不是文件的时候 for 循环已经跑完了,每次 i 都是4,取不到文件,所以最后打印出来是空数组。

    借助 ES6 的 Promise、 async、await 将代码改写如下就能够成功获取到所有文件。

    const basePath = './test'
    let files = []
    
    // 判断是否是文件
    function isFile(path) {
        return new Promise((resolve, reject) => {
            fs.stat(basePath + '/' + path, (err, stats) => {
                if (err) {
                    console.log(err)
                    return
                }
                if (stats.isFile()) {
                    resolve(true)
                } else {
                    resolve(false)
                }
            })
        })
    }
    
    fs.readdir(basePath, async (err, data) => {
        if (err) {
            console.log(err)
            return
        }
        for (var i = 0; i < data.length; i++) {
            if (await isFile(data[i])) {
                files.push(data[i])
            }
        }
        console.log(files) // [ 'aaa.js', 'bbb.html' ]
    })

    Stream(流)

    当文件较大时,可以采用以流的方式读取、写入文件

    读取流:

    var data = ''
    
    const stream = fs.createReadStream('./file.js')
    
    stream.on('data', function (chunk) {
        data += chunk
    })
    
    stream.on('end', function () {
        console.log(data) // 打印出file.js里的内容
    })
    
    stream.on('error', function (err) {
        console.log(err)
    })

    写入流:

    // 写入流
    const data = '写点东西进去'
    var stream = fs.createWriteStream('./writeSteam.js')
    stream.write(data, 'utf-8')
    
    stream.end()
    
    stream.on('finish', function () {
        console.log('写入完成')
    })
    
    stream.on('error', function (err) {
        console.log(err)
    })

    注意:用 nodemon 运行写入流代码会出现死循环,因为每次写入都发生修改,重新触发 nodemon 运行。

    管道流:以流的形式读取、写入文件,可以用来实现大文件的复制

    // 复制file.js到copy.js
    const readStream = fs.createReadStream('./file.js')
    const writeSteam = fs.createWriteStream('./copy.js')
    
    readStream.pipe(writeSteam)
  • 相关阅读:
    rtmp推流
    git 分支操作
    git 当前分支推送的新的仓库地址
    git 修改当前项目的仓库地址,项目迁移,仓库修改
    linux 服务器测试端口连通性
    ffmpeg linux 安装
    rtmp 命令详解
    slf4j和log4j源代码解析以及详解
    聊聊java基础,int值强制类型转换成byte
    应用中并发控制技巧
  • 原文地址:https://www.cnblogs.com/zdd2017/p/14628721.html
Copyright © 2020-2023  润新知