参考:https://www.runoob.com/nodejs/nodejs-fs.html
异步I/O 1,文件操作 2,网络操作
在浏览器中也存在异步操作 1,定时任务 2,事件处理 3,Ajax回调处理
js的运行是单线程的,引入事件队列机制,进入事件队列的任务主要分两种: Node.js中异步执行的任务:1,文件读写操作(文件I/O) 2,网络的请求相应处理(网络I/O)
Node.js中的事件模型与浏览器中的事件模型类型:单线程+事件队列,js的运行是单线程的,Node.js的环境是多线程的
一、获取文件信息
通过异步模式获取文件信息的语法格式
fs.stat(path, callback)
fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件:
常用方法:
var fs = require('fs'); fs.stat('01.js', function(err, stats) { if(err) return; console.log(stats); if(stats.isFile()){ console.log('文件'); } else if(stats.isDirectory()){ console.log('目录'); } });
返回结果:
atime 文件访问时间
ctime 文件状态信息发生变化的时间,比如文件的权限
mtime文件数据发生变化的时间
birthtime文件创建时间
Stats { dev: 3963844000, mode: 33206, nlink: 1, uid: 0, gid: 0, rdev: 0, blksize: 4096, ino: 7599824371308861, size: 326, blocks: 0, atimeMs: 1621577436001.767, mtimeMs: 1621577434724.8518, ctimeMs: 1621577434728.6726, birthtimeMs: 1621505236836.661, atime: 2021-05-21T06:10:36.002Z, mtime: 2021-05-21T06:10:34.725Z, ctime: 2021-05-21T06:10:34.729Z, birthtime: 2021-05-20T10:07:16.837Z }
文件
二、读文件操作
var path = require('path'); var strpath = path.join(__dirname, '02.json'); // 如果没有设置编码方式,那么得到的是Buffer对象,需要进行转换 fs.readFile(strpath, 'utf-8', function(err, data){ console.log(data); });
三、写文件操作
异步模式下写入文件的语法格式:
fs.writeFile(file, data[, options], callback)
writeFile 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。
var fs = require("fs"); console.log("准备写入文件"); fs.writeFile('input.txt', '我是通 过fs.writeFile 写入文件的内容', function(err) { if (err) { return console.error(err); } console.log("数据写入成功!"); console.log("--------我是分割线-------------") console.log("读取写入的数据!"); fs.readFile('input.txt', function (err, data) { if (err) { return console.error(err); } console.log("异步读取文件数据: " + data.toString()); }); });
执行结果:
$ node file.js 准备写入文件 数据写入成功! --------我是分割线------------- 读取写入的数据! 异步读取文件数据: 我是通 过fs.writeFile 写入文件的内容
四、大文件操作(流式操作)
这个只能处理内容量较少的文件,会读取全部内容,将内容加载到内存
fs.createReadStream(path[, options]) 返回ReadStream 对象。
fs.createWriteStream(path[, options]) 返回 WriteStream 对象。
var path = require('path'); var fs = require('fs'); // 源路径 var spath = path.join(__dirname, '../doc', 'css.md'); // 目标路径 var dpath = path.join('D:\\Users\\peiyuli\\Desktop', 'css.md'); var readStream = fs.createReadStream(spath); var writeStream = fs.createWriteStream(dpath); var sum = 0; // 基于事件的处理方式 以chunk(块)为单位,每次读取文件大小时会触发data事件 readStream.on('data', function(chunk){ sum++; writeStream.write(chunk); }); // 数据处理完成标志 end事件 readStream.on('end', function(){ console.log('文件处理完成', sum); });
方法二、简化流程
var path = require('path'); var fs = require('fs'); // 源路径 var spath = path.join(__dirname, '../doc', 'css.md'); // 目标路径 var dpath = path.join('D:\\Users\\peiyuli\\Desktop', 'css.md'); // 管道方法 将读取流和写入流融合到一块 fs.createReadStream(spath).pipe(fs.createWriteStream(dpath));
五、目录的操作
fs.mkdir(path[, options], callback) 创建目录
fs.mkdir(path.join(__dirname, 'abc'), function(err){ console.log(err); });
执行结果:生成了abc目录
fs.readdir(path[, options], callback) 读取目录
var path = require('path'); var fs = require('fs'); fs.readdir(__dirname, function(err, files){ console.log(files); files.forEach(function(item, index){ // 获取文件信息 fs.stat(path.join(__dirname, item), function(err, stat){ // 判断是否为文件 if(stat.isFile()){ console.log(item, '文件'); } else if(stat.isDirectory()){ // 判断是否为目录 console.log(item, '目录'); } }); }); });
执行结果:
fs.rmdir(path[, options], callback) 删除目录
fs.rmdir(path.join(__dirname, 'abc'), function(err){ console.log(err); });