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! \n')

        _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)
posted @ 2018-01-31 14:30  天龙久传说  阅读(486)  评论(0编辑  收藏  举报