zoukankan      html  css  js  c++  java
  • fs文件系统

    本文转载于:http://blog.csdn.net/wade333777/article/details/69218537

    一、概述

    Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示: 

    var fs = require("fs")
    

    API文档:http://www.runoob.com/nodejs/nodejs-fs.html

    require(‘readline’) 模块提供了一个接口,用于从可读流(如 process.stdin)读取数据,每次读取一行。 它可以通过以下方式使用: 

    const readline = require('readline');
    

    API文档:http://nodejs.cn/api/readline#readline_rl_write_data_key

    1.异步和同步

    Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。 
    异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。 
    建议大家是用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。

    // 同步读取
    var data = fs.readFileSync('input.txt');
    console.log("同步读取: " + data.toString());
    
    // 异步读取
    fs.readFile('input.txt', function (err, data) {
       if (err) {
           return console.error(err);
       }
       console.log("异步读取: " + data.toString());
    });
    

    2.打开文件

    以下为在异步模式下打开文件的语法格式: 

    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.open('input.txt', 'r+', function(err, fd) {
       if (err) {
           return console.error(err);
       }
      console.log("文件打开成功!");     
    });
    

    3.获取文件信息

    fs.stat(path, callback)
    

    参数使用说明如下: 
    path - 文件路径。 
    callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。 
    fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件:

    fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
        console.log(stats.isFile());        //true
    })
    

    4.写入文件

    以下为异步模式下写入文件的语法格式: 

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

    如果文件存在,该方法写入的内容会覆盖旧的文件内容。 
    参数使用说明如下: 
    path - 文件路径。 
    data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(流) 对象。 
    options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 ‘w’ 
    callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。 

    5.读取文件

    以下为异步模式下读取文件的语法格式: 

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

    该方法使用了文件描述符来读取文件。 
    参数使用说明如下: 
    fd - 通过 fs.open() 方法返回的文件描述符。 
    buffer - 数据写入的缓冲区。 
    offset - 缓冲区写入的写入偏移量。 
    length - 要从文件中读取的字节数。 
    position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。 
    callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。 

    6.关闭文件

    以下为异步模式下关闭文件的语法格式: 

    fs.close(fd, callback)
    

    该方法使用了文件描述符来读取文件。 
    参数使用说明如下: 
    fd - 通过 fs.open() 方法返回的文件描述符。 
    callback - 回调函数,没有参数。 

    其他方法描述
    fs.rename(oldPath, newPath, callback) 文件重命名
    fs.unlink(path, callback) 删除文件
    fs.readdir(path, callback) 读取目录
    fs.createReadStream(path[, options])返回ReadStream 对象 读取大文件
    fs.createWriteStream(path[, options]) 写大文件

    二、实战

    公司项目平时处理BUG积攒了大量的垃圾输出标记print语句,所以就想写个工具干掉这些垃圾语句,最近也是喜欢研究nodejs这种前后端通吃的语言,索性就拿来练练手: 

    // 删除文件中的特殊符号信息(删除print标记)
    // 1.遍历当前目录,判断是否是文件
    // 2.不是文件是目录,继续递归遍历
    // 3.是文件,开始做特殊处理,一行一行读取,开始做处理
    // 4.判断当前行内容中是否有print
    // 5.有的话,读完文件后替换源文件,没有的话则跳过到下一个文件
    
    const fs = require('fs')
    const readline = require('readline')
    const os = require('os')
    
    //要处理的特殊字符
    var special_chars = ['print']
    
    console.log('当前执行目录:'+__dirname)
    
    //列表当前目录中的文件
    function listFile(_dir_name){
        fs.readdir(_dir_name,function(_err,_files){
            if(_err)
                return console.log(_err)
    
            if(!_files.length)
                return console.log(_dir_name + ' have no files to show! 
    ')
    
            _files.forEach(function(_file_name){
                if(filterFile(_file_name)){
                    var full_name = _dir_name + '/' + _file_name
                    fs.stat(full_name,function(_err,_stat){
                        if(_stat.isDirectory())
                            listFile(full_name)
                        else
                            dealFile(full_name)
                    })
                }
            })
        })
    }
    
    // 拆分全路径下的路径和文件名
    function splitPathFile(_full_name){
        if(_full_name == '')
            throw('splitPathFile _full_name is null')
    
        var __s = _full_name.split('/')
        var __file_name = __s[__s.length-1]
        var __path_name = ''
    
        if(__s.length > 1){
            for (var i = 0; i <= __s.length-2; i++) {
                __path_name = __path_name + __s[i] + '/'
            }
        }
    
        return [__path_name,__file_name]
    
    }
    
    // 处理文件
    function dealFile(_full_name){
        console.log('dealFile:'+_full_name)
    
        var __is_special = false
        var __path_name = splitPathFile(_full_name)[0]
        var __file_name = splitPathFile(_full_name)[1]
        var __tmp_name = __path_name + __file_name + 'tmp.txt'
        var __output = fs.createWriteStream(__tmp_name)
    
        var rl = readline.createInterface({
            input : fs.createReadStream(_full_name),
            output : __output
        })
    
        rl.on('line',function(_line){
            // console.log('文件单行内容:'+_line)
            var __is = filterSpecialChar(_line)
    
            if(__is){
                __is_special = true
                console.log('__is_special = true')
            }else{
                __output.write(_line + os.EOL)
            }
    
        })
    
        rl.on('close',function(){
            console.log(_full_name + " is closed")
    
            if(__is_special){
                fs.unlink(_full_name,function(_err){
                    if(_err){
                        return console.log(_err)
                    }
    
                    fs.rename(__tmp_name,_full_name,function(_err){
                        if(_err){
                            return console.log(_err)
                        }
    
                        console.log('文件处理完毕1:' + _full_name)
    
                    })
                })
            }else{
                fs.unlink(__tmp_name,function(_err){
                    if(_err){
                        return console.log(_err)
                    }
    
                    console.log('文件处理完毕2:' + _full_name)
                })
            }
        })
    }
    
    // 过滤特殊字符
    function filterSpecialChar(_str){
    
        var __is = false
        _str = _str.trim()
        // console.log(_str.indexOf('print'))
    
        for(var i =0;i < special_chars.length;i++){
            if(_str.indexOf(special_chars[i]) == 0){
                return true
            }
        }
    
        return false
    }
    
    //过滤器,做文件过滤工作,例如.DS_Store文件
    function filterFile(_file_name){
        if(_file_name.charAt(0) == '.')
            return false
    
        return true
    }
    
    listFile(__dirname)
  • 相关阅读:
    一篇文章高效定位iframe
    URL与视图函数的映射
    include标签—引用文件路径
    UnitTest单元测试框架解析【实用篇】
    【案例演练】测试器与模板继承
    2招带你快速获取响应头与发送头
    dede网站如何更新地图sitemap.html
    申请微信小程序流程步骤
    phpstudy本地配置--dede织梦网
    stylus样式开发的使用----vue
  • 原文地址:https://www.cnblogs.com/guangyun/p/8392074.html
Copyright © 2011-2022 走看看