在学习fs之前首先我们得了解一些操作系统于文件的基础知识:
- 权限位 mode
- 标识位 flag
- 描述符 fd
-
权限位mode
简单介绍一下Linux的文件操作方面的知识:
Linux系统上对文件的权限有着严格的控制,用于如果相对某个文件执行某种操作,必须具有对应的权限。
Linux下文件的权限类型一般包括读,写,执行。对应字母为r、w、x。对应的数字表示为八进制数,具备权限的八进制数分别为 4(r) 、2(w)、1(x),不具备权限为 0(-)。
Linux下权限的粒度有 拥有者 、群组 、其它组三种。
每个文件都可以针对三个粒度,设置不同的rwx(读写执行)权限。 通常情况下,一个文件只能归属于一个用户和组,如果其它的用户想有这个文件的权限,则可以将该用户加入具备权限的群组,一个用户可以同时归属于多个组。
Window的权限默认是可读、可写、不可执行,所以权限位数字表示为0o666,转换十进制表示为 438
Linux上通常使用chmod命令对文件的权限进行设置和更改。
为了更容易理解,我们可以随便在一个目录中打开 Git,使用 Linux 命令 ls -al 来查目录中文件和文件夹的权限位
drwxr-xr-x 1 PandaShen 197121 0 Jun 28 14:41 core -rw-r--r-- 1 PandaShen 197121 293 Jun 23 17:44 index.md第一位代表是文件还是文件夹,d 开头代表文件夹,- 开头的代表文件,而后面九位就代表当前用户、用户所属组和其他用户的权限位,按每三位划分,分别代表读(r)、写(w)和执行(x),- 代表没有当前位对应的权限。
-
标识位 flag
之前所说的权限位就是和标识位有着一些细微的关系。
标识位就是意味着你对文件的操作方式。读写执行。
flag 是不经常使用的,不容易被记住,所以在下面总结了一个加速记忆的方法。
- r:读取
- w:写入
- s:同步
- +:增加相反操作
- x:排他方式
r+ 和 w+ 的区别,当文件不存在时,r+ 不会创建文件,而会抛出异常,但 w+ 会创建文件;如果文件存在,r+ 不会自动清空文件,但 w+ 会自动把已有文件的内容清空。
-
描述符 fd
操作系统会为每个打开的文件分配一个名为 文件描述符 的数值标识。
在使用文件操作的时候,便是根据这个文件描述符去识别你在操作什么文件。
Window 系统使用了一个不同但概念类似的机制来追踪资源,为方便用户,NodeJS抽象了不同操作系统间的差异,为所有打开的文件分配了数值的文件描述符。
在 NodeJS 中,每操作一个文件,文件描述符是递增的,文件描述符一般从 3 开始。
因为前面有 0、1、2三个比较特殊的描述符,分别代表 process.stdin(标准输入)、process.stdout(标准输出)和 process.stderr(错误输出)。
熟知了文件的一些基础之后,就可以进入node的文件模块学习时间。
-
文件完整读/写
什么是完整的读写?就是你一下扛一袋米上楼,不带喘气的。你就是完整的扛米,电脑呢就是完整的读写。一样的道理。
-
文件的读取
fs.readFile(filename, [encoding], [callback(error,data)]- 第一个变量就是文件所在地点
- 第二个第二个参数为 options,默认值为 null,其中有 encoding(编码,默认为 null)和 flag(标识位,默认为 r),也可直接传入 encoding;(不传就会读取buffer二进制数据)
- 第三个就是回调函数 以下读取文件操作
const fs = require('fs'); //异步方法 fs.readFile('./file/readFile.txt','utf8', function(err, data) { if (err) { throw err; } // 读取文件成功 console.log(data); }); //同步方法 var data = fs.readFileSync('./file/readFile.txt','utf-8'); console.log(data); -
文件的写入
fs.writeFile(filename, data, [options], callback)- 第一个参数为写入文件的路径或文件描述符;
- 第二个参数为写入的数据,类型为 String 或 Buffer;
- 第三个参数为 options,默认值为 null,其中有 encoding(编码,默认为 utf8)、 flag(标识位,默认为 w)和 mode(权限位,默认为 0o666),也可直接传入 encoding。
encoding {String | null} default='utf-8' mode {Number} default=438(aka 0666 in Octal) flag {String} default='w' // w表示在写入之前清空原内容以下是一个例子
const fs = require('fs'); // 写入文件内容(如果文件不存在会创建一个文件) // 写入时会先清空文件 fs.writeFile('./file/writeFile.txt', '写入成功:hello world', function(err) { if (err) { throw err; } // 写入成功后读取测试 var data=fs.readFileSync('./file/writeFile.txt', 'utf-8'); console.log('new data -->'+data); }); // 数据追加 setTimeout(function(){ // 追加 fs.writeFile('./file/writeFile.txt', '这里是追加的数据', {'flag':'a'},function(err) { if (err) { throw err; } console.log('success'); var data=fs.readFileSync('./file/writeFile.txt', 'utf-8') // 写入成功后读取测试 console.log('追加后的数据 -->'+data); }); },1000); -
文件的追加写入
当然,我们不可能每次写入都是清空了在写东西的,我们大多数时候都是喜欢在文件的末尾添加数据。例如你有一篇文档就差一句总结就完成了,我们就需要追加写入了。
fs.appendFile(filename, data, [options], callback)- 第一个参数为写入文件的路径或文件描述符;
- 第二个参数为写入的数据,类型为 String 或 Buffer;
- 第三个参数为 options,默认值为 null,其中有 encoding(编码,默认为 utf8)、 flag(标识位,默认为 a)和 mode(权限位,默认为 0o666),也可直接传入 encoding。
fs.appendFile("3.txt", " world", err => { if (!err) { fs.readFile("3.txt", "utf8", (err, data) => { console.log(data); // Hello world }); } }); fs.appendFileSync("3.txt", " world"); let data = fs.readFileSync("3.txt", "utf8"); console.log(data); // Hello world -
文件的拷贝写入
fs.copyFile(sourceFile, operationFile)
-
第一个参数为被拷贝文件
-
第二个参数为拷贝到的目标文件路径,如果目标文件不存在,则会创建并拷贝
fs.copyFile("3.txt", "4.txt", () => { fs.readFile("4.txt", "utf8", (err, data) => { console.log(data); // Hello world }); }); function copy(src, dest) { let data = fs.readFileSync(src); fs.writeFileSync(dest, data); } copy("3.txt", "4.txt"); let data = fs.readFileSync("4.txt", "utf8"); console.log(data); // Hello world
以上便是fs模块的基础用法,下次将介绍一些高级的使用方法。