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)