第十一篇:node js 之fs 模块系统(File System)
什么是文件系统:借用 node 环境使用用js代码可以操作计算机硬盘文件的系统
fs模块非常的重要 因为服务器的本质就是将本地文件 通过浏览器等软件 发送到客户端
第一步需要安装 node js
使用语法以及API操作如下:
使用 require 方法 引入fs模块 node中操作文件的封装对象
const fs = require('fs');
一、【同步操作文件的方法】 (该方法会阻塞程序的运行)
文件的写入: fs.openSync(path[, flags[, mode]])
path:要写入的文件路径 可以是相对地址也可以是绝对地址
flags:
文件打开的行为 常用值如下图
常用值 r 只读 w 可读写 a对文件追加操作
mode - 设置文件模式(权限) 一般不用写
// fd 为文件打开的标志 是一个数字
let fd = fs.openSync('./hello.txt','a');//a 表示追加写入内容 不影响原文件
//调用写入文件的API方法
fs.writeSync(fd,'我是写入的内容',30);//30 意思是从第几个字符开始写入
//打开文件写入文件完之后 对于服务器而言 要调用一个 关闭文件的方法 否则一直打开状态
fs.closeSync(fd); //到此文件的写入操作完毕
简单文件的写入
fs.writeFileSync(path,‘要写入的内容’,{flag:'a'}) ;
fs.writeFileSync('./hello.txt','我是简单写入的文件',{flag:'a'}) ;
文件的读取
ffs.readSync(fd, buffer, offset, length[, position])
-
fd - 通过 fs.open() 方法返回的文件描述符。
-
buffer - 数据写入的缓冲区。
-
offset - 缓冲区写入的写入偏移量。
-
length - 要从文件中读取的字节数。
-
position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
let fd = fs.openSync('./hello.txt','r');
//实例一个存储二进制数据的缓冲区
let buf_1 = new Buffer.alloc(1024);
// 该方法返回的是读取的字节的数量
let len = fs.readSync(fd,buf_1,0,buf_1.length,null);
console.log(len);
//截取缓冲区中存储的数据
console.log(buf_1.slice(0, len).toString());
//关闭文件
fs.closeSync(fd);
简单文件的读取
fs.readlinkSync(path[, options])
let data = fs.readFileSync('./hello.txt',{flag:'r'});
console.log(data.toString());
二 、【异步操作文件的方法】
文件的写入 fs.open(path[, flags[, mode]], callback)
fs.open('./hello.txt','a',(err,fd)=>{
// 如果出错直接抛出错误
if(err) throw err;
// 没出错则运行下面的代码
fs.write(fd,'\r这是异步写入的文件',err=>{
// 如果出错 抛出错误
if(err) throw err;
// 否则运行下面的代码
console.log('写入成功');
});
//调用关闭文件的回调
fs.close(fd,err=>{
if(err) throw err;
console.log('文件已关闭');
})
});
简单的文件写入 fs.writeFile(file, data[, options], callback)
fs.writeFile('./hello.txt','\n这是简单异步写入的文件',{flag:'a'},err=>{
if(err) throw err;
console.log('简单异步写入成功');
})
文件的读取 fs.read(fd, buffer, offset, length, position, callback) 同上 同步的读取
const fs = require("fs");
const buf_1 = new Buffer.alloc(1024);
console.log("准备打开已存在的文件!");
fs.open('./hello.txt', 'r', function(err, fd) {
if (err) throw err;
console.log("文件打开成功!");
console.log("准备读取文件:");
fs.read(fd, buf_1, 0, buf_1.length, 0, function(err, bytes){
if (err) throw err;
console.log(bytes + " 字节被读取");
// 仅输出读取的字节
if(bytes > 0){
console.log(buf_1.slice(0, bytes).toString());
}
//调用关闭文件的方法
fs.close(fd,()=>{
if (err) throw err;
console.log('文件已关闭');
})
});
});
简单文件的读取 fs.readFile(path[, options], callback)
fs.readFile('./hello.txt',{flag:'r'},(err,data)=>{
if(err) throw err;
console.log(data.toString());
})
三 、【流式操作大文件】
流式写入文件
//第一步创建一个写入文件的流(通道)
let ws = fs.createWriteStream('./hello.txt',{flags:'a'});
//可以开启监听流的打开关闭事件
//查看可写流是否开启
ws.once('open',()=>{
console.log('写入流开启了');
})
// 通过写入流写入文件
ws.write('\n我是流写入的文件');
ws.write('\n我是流写入的文件');
ws.write('\n我是流写入的文件');
// 若要关闭可写流需要调用 ws.end() 的方法
ws.end();
// 查看可写流是否关闭
ws.once('close',()=>{
console.log('可写流关闭了');
});
流式读取文件
let rs = fs.createReadStream('./hello.txt',{flags:'r'});
// 查看可读流是否开启
rs.once('open',()=>{
console.log('可读取流开启了');
});
rs.on('data',chunk=>{
console.log(chunk.toString());
});
// 查询可读流是否关闭 当文件读取完毕 会自动关闭可读流
rs.once('close',()=>{
console.log('关闭可读流');
})
用读写流复制文件
// 创建一个可读流
const rs = fs.createReadStream('../coures-01.mp4');
// 创建一个可写流
const ws = fs.createWriteStream('../02.mp4');
//方法一通过管道流 边读边写
rs.pipe(ws);
// 方法二 一边读取一边写入
rs.on('data',(chunk)=>{
//写入文件
ws.write(chunk);
});
// 方法三 连接流 读取写入压缩文件
const zlib = require('zlib');
rs.pipe(zlib.createGzip())
.pipe(require('fs').createWriteStream('../02.zip'));
// 总结:文件的复制 实质就是读取需要复制的文件 然后将读取的文件
// 写入到新的文件中 也就是新建了一个内存来存一样的数据
四【文件以及问件夹的其他操作 】
文件的删除
const fs = require('fs');
// unlink & rm
fs.unlinkSync('./hello2.txt');
fs.unlink('./hello2.txt',err=>{
if(err) throw err;
console.log('删除成功');
})
fs.rm('./file.js',err=>{
if(err) throw err;
console.log('删除成功');
})
fs.rmSync('./hello2.txt');
文件的重命名和移动
const fs = require('fs');
// 重命名
fs.renameSync('./hello2.txt','./02.txt');
fs.rename('./02.txt','./hello2.txt',err=>{
if (err) throw err;
console.log('修改成');
})
移动
fs.rename('./hello2.txt','./02/hello2.txt',err=>{
if (err) throw err;
console.log('移动成功');
})
fs.renameSync('./02/hello2.txt','02.txt');
文件夹的创建
const fs = require('fs');
// fs.mkdirSync('./04',{recursive:true});
//批量创建文件夹
for(let i=5;i<10;i++){
fs.mkdirSync(`./0${i}`,{recursive:true});
}
fs.mkdir('./test',{recursive:true},err=>{
if(err) throw err;
console.log('创建成功');
fs.mkdir('test/01',{recursive:true},err=>{
if(err) throw err;
console.log('创建test/01成功');
});
fs.mkdir('test/02',{recursive:true},err=>{
if(err) throw err;
console.log('创建test/02成功');
});
fs.mkdir('test/03',{recursive:true},err=>{
if(err) throw err;
console.log('创建test/03成功');
});
fs.writeFile('test/index.html','哈哈我是文件',{flag:'w'},err=>{
if(err) throw err;
console.log('创建并写入写入成功');
})
})
文件夹的删除
const fs = require('fs');
fs.rmdirSync('./02');
fs.rmdir('./03',()=>{
console.log('删除成功');
});
文件目睹的读取
const fs = require('fs');
let res = fs.readdirSync('C:/Users/Admin/Desktop/node-fs系统');
console.log(res);
fs.readdir('C:/Users/Admin/Desktop/node-fs系统',(err,files)=>{
if(err) throw err;
console.log(files);
})
文件信息的获取
// 查看资源的状态 stat
const fs = require('fs');
//
fs.stat('01.mp4',(err,stats)=>{
if(err) throw err;
// stats 是一个对象 内置了很多的方法
console.log('是否是个文件'+stats.isFile());
console.log('是否是个文件夹'+stats.isDirectory());
console.log('是否是个块设备'+stats.isBlockDevice());
console.log('是否是字符设备'+stats.isCharacterDevice());
console.log('是否是软连接'+stats.isSymbolicLink());
console.log('是否是FIFO'+stats.isFIFO());
console.log('是否是soket'+stats.isSocket());
})