• 每天学点node系列-fs文件系统(续)


    理想如果不向现实做一点点屈服,那么理想也将归于尘土。

    创建目录

    异步创建目录

    path<string> | <Buffer> | <URL>
    options <Object> | <integer>
      - recursive <boolean> 默认值: false。
      - mode <integer> Windows 上不支持。默认值: 0o777。
    callback <Function>
      - err <Error></Error>
    
    // fs.mkdir(path[, mode], callback)
    var fs = require('fs')
    fs.mkdir('sub', function(err){
        if(err) throw err
        console.log('创建目录成功')
    })
    

    执行结果:

    $ node 1.js
    创建目录成功
    

    同步创建目录

    path<string> | <Buffer> | <URL>
      - options <Object> | <integer>
      - recursive <boolean> 默认值: false。
    mode <integer> Windows 上不支持。默认值: 0o777。
    
    // fs.mkdirSync(path[, mode])
    var fs = require('fs')
    try{
        fs.mkdirSync('rock')
        console.log('创建目录成功')
    }catch(e){
        throw e
    }
    

    执行结果:

    $ node 1.js
    创建目录成功
    

    读取目录

    异步读取目录

    path<string> | <Buffer> | <URL>
    options <string> | <Object>
      - encoding <string> 默认值: 'utf8'。
      - withFileTypes <boolean> 默认值: false。
    callback <Function>
      - err <Error>
      - files <string[]> | <Buffer[]> | <fs.Dirent[]></Error>
    

    注意: files 是目录中的文件名的数组(不包括 '.' 和 '..')

    let fs = require('fs')
    fs.readdir('./sub', 'utf8', (err, files) => {
        if (err) console.log(err)
        console.log(files)
    })
    

    执行结果:

    $ node 1.js
    [ '1.css', 'index.html' ]
    

    同步读取目录

    path <string> | <Buffer> | <URL>
    options <string> | <Object>
      - encoding <string> 默认值: 'utf8'。设置为 'buffer',则返回的文件名是 Buffer 对象。
      - withFileTypes <boolean> 默认值: false。 设置为 true,则返回的结果将包含 fs.Dirent 对象。
    返回: <string[]> | <Buffer[]> | <fs.Dirent[]></boolean>
    
    let fs = require('fs')
    try {
        let result = fs.readdirSync('./sub', 'utf8')
        console.log(result)
    } catch (error) {
        console.log(error)
    }
    

    执行结果:

    $ node 1.js
    [ '1.css', 'index.html' ]
    

    遍历目录

    var fs = require('fs')
    var path = require('path')
    var getFilesInDir = function (dir) {
        var results = [path.resolve(dir)]
        var files = fs.readdirSync(dir, 'utf8')
        files.forEach(function (file) {
            file = path.resolve(dir, file)
            var stats = fs.statSync(file)
            if (stats.isFile()) {
                results.push(file)
            } else if (stats.isDirectory()) {
                results = results.concat(getFilesInDir(file))
            }
        })
        return results
    }
    var files = getFilesInDir('./api');
    console.log(files);
    

    注意:fs.readdirSync()只会读一层,所以需要判断文件类型是否目录,如果是,则进行递归遍历。

    执行结果:

    $ node 1.js
    [ 'C:\Users\Administrator\Desktop\api',
      'C:\Users\Administrator\Desktop\api\config.1.json',
      'C:\Users\Administrator\Desktop\api\config.json',
      'C:\Users\Administrator\Desktop\api\config16.json',
      'C:\Users\Administrator\Desktop\api\integral-consumpte'
    ...
    

    修改权限

    path <string> | <Buffer> | <URL>
    mode <integer>
    callback <Function>
      - err <Error>
    
    var fs = require('fs')
    fs.chmod('1.txt', '777', function (err) {
        if (err) {
            console.log(err)
        } else {
            console.log("change done")
        }
    })
    

    同步修改所有者

    path <string> | <Buffer> | <URL>
    mode <integer>
    
    var fs = require('fs')
    fs.chmodSync('./1.txt', '777')
    

    访问/权限检测

    path<string> | <Buffer> | <URL>
        mode <integer> 默认值: fs.constants.F_OK。
        callback <Function>
      - err <Error></Error>
    
    
    const fs = require('fs')
    const file = '1.txt';
    // 检查当前目录中是否存在该文件。
    fs.access(file, fs.constants.F_OK, (err) => {
        console.log(`${file} ${err ? '不存在' : '存在'}`);
    });
    // 检查文件是否可读。
    fs.access(file, fs.constants.R_OK, (err) => {
        console.log(`${file} ${err ? '不可读' : '可读'}`);
    });
    // 检查文件是否可写。
    fs.access(file, fs.constants.W_OK, (err) => {
        console.log(`${file} ${err ? '不可写' : '可写'}`);
    });
    // 检查当前目录中是否存在该文件,以及该文件是否可写。
    fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
    if (err) {
        console.error(
            `${file} ${err.code === 'ENOENT' ? '不存在' : '只可读'}`);
        } else {
            console.log(`${file} 存在,且它是可写的`);
        }
    });
    

    执行结果:

    $ node 1.js
    1.txt 存在
    1.txt 可读
    1.txt 可写
    1.txt 存在,且它是可写的
    

    不建议在调用 fs.open()、 fs.readFile() 或 fs.writeFile() 之前使用 fs.access() 检查文件的可访问性。 这样做会引入竞态条件,因为其他进程可能会在两个调用之间更改文件的状态。 相反,应该直接打开、读取或写入文件,如果文件无法访问则处理引发的错误。

    写入(不推荐)

    
    const fs = require('fs')
    const file = '1.txt'
    fs.access(file, (err) => {
        if (!err) {
            console.error(`${file} 已存在`)
            return
        }
        fs.open(file, 'wx', (err, fd) => {
            if (err) throw err
            writeMyData(fd)
        })
    })
    

    写入(推荐)

    const fs = require('fs')
    fs.open('1.txt', 'wx', (err, fd) => {
        if (err) {
            if (err.code === 'EEXIST') {
                console.error('1.txt 已存在')
                return
            }
            throw err
        }
        writeMyData(fd)
    })
    

    同步访问/权限检测

    path<string> | <Buffer> | <URL>
    mode <integer> 默认值: fs.constants.F_OK。
    

    注意: 如果可访问性检查失败,则抛出 Error。 否则,该方法将返回 undefined。

    try {
        fs.accessSync('./1.txt', fs.constants.R_OK | fs.constants.W_OK)
        console.log('可以读写')
    } catch (err) {
        console.error('无权访问')
    }
    

    删除目录

    异步删除目录

    path<string> | <Buffer> | <URL>
    callback <Function>
      - err <Error>
    

    注意:在文件(而不是目录)上使用 fs.rmdir() 会导致在 Windows 上出现 ENOENT 错误、在 POSIX 上出现 ENOTDIR 错误。

    var fs = require('fs')
    
    fs.rmdir('./rock', function(err){
        if(err) throw err
        console.log('目录删除成功')
    })
    

    同步删除目录

    path <string> | <Buffer> | <URL>
    
    var fs = require('fs')
    fs.rmdirSync('./rock')
    

    实用场景

    文件锁

    使用独占标记创建锁文件

    fs模块为所有需要打开文件的方法提供了一个x标记。这告诉操作系统这个文件应该以独占模式打开(O_EXCL)。当使用这个方法时,若这个文件存在,文件不能被打开。

    
    

    文件数据库

    策略是不断的追加记录,在处理的时候不断的覆盖原始记录。

    var fs = require('fs')
    var EventEmitter = require('events').EventEmitter
    var Database = function (path) {
        this.path = path
        // 数据库key/value映射表
        this._records = Object.create(null)
        this._writeStream = fs.createWriteStream(this.path, {
            encoding: 'utf8',
            flags: 'a'
        })
        this._load()
    }
    // 继承自EventEmitter,让它有可以监听事件、传递事件的功能
    Database.prototype = Object.create(EventEmitter.prototype)
    Database.prototype._load = function () {
        var stream = fs.createReadStream(this.path, { encoding: 'utf8' })
        var database = this
        var data = ''
        // 当输入流准备好时触发
        stream.on('readable', function () {
            data += stream.read()
            // 每一行是一组数据
            var records = data.split('
    ')
            data = records.pop()
            for (var i = 0; i < records.length; i++) {
                try {
                    var record = JSON.parse(records[i])
                    if (record.value == null) {
                        delete database._records[record.key]
                    } else {
                        database._records[record.key] = record.value
                    }
                } catch (e) {
                    database.emit('error', 'found invalid record:', records[i])
                }
            }
        })
        // 流处理完后发送load事件给消费者
        stream.on('end', function () {
            database.emit('load')
        })
    }
    let database = new Database('./sub/a.txt')
    database._writeStream.write('beep')
    
  • 相关阅读:
    sql mysql
    sql练习
    re正则表达式
    《大道至简 第二章》读后感
    读《大道至简:编程的精义》有感
    爬取汽车之家新闻图片的python爬虫代码
    Linux系统封装成iso文件
    使用Zabbix进行IPMI监控
    zabbix支持的主要监控方式
    python虚拟环境搭建
  • 原文地址:https://www.cnblogs.com/jingh/p/11166625.html
Copyright © 2020-2023  润新知