fs : file system,文件系统。提供读取文件的方法,让代码取完成计算机的CRUD(增删改查)。javascript
注意两个点:☛ 文件和文件夹对于程序而言都属于文件系统;html
☛ 文件名包括自定义文件名.扩展文件名(后缀名)java
在了解文件系统以前,咱们先来了解两个概念:文件权限和递归算法。node
☛ 权限算法
在控制台(这里是Mac系统)输出 “ls -l”,能够看到当前文件夹下面的文件权限。如:-rw-r--r--,drwxr-xr-x等。其中,r 表示read,可读,表明数字 4;w 表示write,可写,表明数字 2;x 表示execute,可执行,表明数字 1。因此,7=4+2+1表示可读可写可执行(好多地方会用数字表示权限)。编程
那么,为何 r 表明数字4,w 表明数字2,x 表明数字 1 呢?app
咱们用“_(是否可读) _(是否可写) _(是否可执行)” 这顺序记好(读 写 执行),由于计算机中用二进制计数,因此这里拥有该权限用 1 表示,没有该权限用 0 表示。因此,用二进制 111 表示( rwx )可读可写可执行,二进制 111 转为 十进制(2^2+2^1+2^0=4+2+1)得 7。同理,只读权限(可读 不可写 不可执行)( r_ _ ),用二进制表示为 100,转为十进制(2^2)4 ;只写权限(不可读 可写 不可执行)( _w_ ),用二进制表示为 010,转为十进制(2^1)2 ;只操做权限(不可读 不可写 可执行)( _ _x ),用二进制表示为 001 ,转为二进制(2^0)1 等。相反,根据数字十进制 0-7 咱们也可转为二进制 知道其具体权限。异步
既然咱们已经知道权限对应字母和数字所表明的权限。那么咱们来看一下这个“-rw-r--r--”,分四个部分看“-|rw-|r--|r--”:函数
第一部分:表示文件类型。常见类型 d 文件夹;-普通文件; l (link) 连接;b 块设备文件;p 管道文件;c 字符设备文件;s 套接口文件。ui
第二部分:对当前用户权限;第三部分:对同组用户权限;最后部分:对其它用户权限。
因此,权限 777 表示对当前用户可读可写可执行,对同组用户可读可写可执行,对其它用户可读可写可执行。
☛ 递归(这里讲递归的缘由是后面讲文件深度时会用到,能理解多少看我的)
程序调用自身的编程技巧称为递归( recursion)。递归作为一种算法在程序设计语言中普遍应用。
简单的认识一下递归:使用递归方式实现 n! (1*2*3*...*n)。由于 n! = (n-1)! * n,因此具体实现以下:
function doFun(n){//定义函数 n! if(n==1) return 1;//函数的出口 return doFun(n-1)*n;//n!=(n-1)!*n,调用函数自己,参数改变。 } let s = doFun(10);//做 10! 运算 console.log(s);
上述代码实现了用递归思想运算 n!。由代码咱们能够看出递归的几点要求:1. 能调用自己(常见的是函数);2. 调用自身,多层数据嵌套;3. 为了避免陷入死循环,必需提供明确的结束出口。
文件的操做分为文件夹的CRUD(增删改查)和文件的CRUD。
node.js 中,fs 文件系统模块提供读取文件的方法,让代码取完成计算机的CRUD(增删改查)。
☛ 文件夹的操做(callback指的是回调函数)
☛ 文件夹的建立
异步方法:fs.mkdir(path [,mode] ,callback)
同步方法:fs.mkdirSync(path [,mode])
☛ 文件夹的删除(必定要保证文件夹是空的)
异步方法:fs.rmdir(path , callback)
同步方法:fs.rmdirSync(path)
☛ 文件夹的修改
☛ 权限修改
权限问题不能实现官网上描述效果,这里就 不写了。
☛ 文件夹名称的修改
异步方法:fs.rename(oldPath , newPath , callback)
同步方法:fs.renameSync(oldPath , newPath)
☛ 文件夹的读取(读取深度为1,即只能读取一层文件夹)
异步方法:fs.readdir(path [, options] , callback)
同步方法:fs.readdirSync(path [, options])
☛ 文件的操做
☛文件的建立和写入
异步方法:fs.writeFile(path,data,callback)
同步方法:fs.writeFileSync(path,data)
☛ 文件的删除(取消硬链接)(具备权限)
异步方法:fs.unlink(path , callback)
同步方法:fs.unlinkSync(path)
☛ 文件的读取
异步方法:fs.readFile(path , callback)
同步方法:fs.readFileSync(path)
☛ 文件的追加(文本文件)
异步方法:fs.appendFile(file , data [, options] , callback)
同步方法:fs.appendFileSync(file , data [,options])
· file参数就是已经存在的文件路径
· 若是文件不存在,会自动建立一个新的文本文件
☛ 文件的修改
☛ 权限修改
☛ 文件名称的修改
异步方法:fs.rename(oldPath , newPath , callback)
同步方法:fs.renameSync(oldPath , newPath)
如下代码中,全部回调函数中 error 返回 null 表示成功。
全部文件操做的方法都有同步和异步两种方法。
一、文件夹的操做(callback指的是回调函数)
1.1 文件夹的建立
异步方法:
// 在加载模块时 const fs = require("fs"); // 建立文件夹 mkdir // 异步方法 ==> callback 回调 // fs.mkdir(path [,mode] ,callback); // path 路径/文件夹名称 支持绝对路径和相对路径 // callback(error) 执行完成后的回调函数,参数error 为错误消息 // mode (可省略)用于指定文件夹得权限,用777数字形式这种表示权限 // 由于系统的问题,权限相关可能没法达到API 中所描述的功能 fs.mkdir("./newdir01",(error)=>{// ./ 当前文件夹下,newdir01文件夹 if(error){ console.log("文件夹建立失败:"+error.message);//打印错误消息 return; } console.log("建立完成"); });
当建立成功时(当前文件夹下面没有newdir01文件或文件夹),控制台打印:建立完成;
当建立失败时(当前文件夹下面存在newdir01文件或文件夹),控制台打印:文件夹建立失败:EEXIST: file already exists, mkdir 'C:\Users\qiuji\Desktop\myNode.js\fs\newdir01' (英文部分是: error.message)。
1.2 文件夹的删除(必定要保证文件夹是空的)
同步方法:同步方法使用try{ ... }catch(error){ ... } 捕获错误信息
// 文件夹的删除 const fs = require("fs"); try { fs.rmdirSync("./newdir01"); console.log("执行成功"); } catch (error) { console.log("执行失败:"+error.message); }
当目标文件夹中存在文件或文件夹时,删除失败,返回错误信息:执行失败:ENOTEMPTY: directory not empty, rmdir 'C:\Users\qiuji\Desktop\myNode.js\fs\newdir01';(要删除的文件夹必需为空)
1.3 文件夹的修改
1.3.1 权限修改
1.3.2 文件夹名称的修改
异步方法:
// 文件名修改,文件夹和文件方法彻底相同 const fs = require("fs"); // 不是真正的改名 // 一、复制 二、删除 三、建立 fs.rename("./newdir01","./文件夹",(error)=>{ console.log(error); });
上述代码的做用是把当前路径下的名为“newdir01”的文件夹更名为“文件夹”。修改文件名的实际操做是先复制再删除再建立的过程。因此,文件夹路径能够改变,如“../文件夹”,能够本身试一下。文件的更名方法和文件夹的更名方法彻底相同,注意不要落下文件的扩展名。
1.4 文件夹的读取(读取深度为1,即只能读取一层文件夹)
const fs = require("fs"); fs.readdir("./newdir01",(err,files)=>{ if(err){ console.log("读取失败"+err.message); return; } console.log(files); });
以下图所示,是我当前newdir01文件夹的目录和读取结果:
二、文件的操做(同步方法和异步方法都能实现)
2.1 文件的建立和写入
异步方法:
// 文件的操做 const fs = require("fs"); // 文件的建立和写入 集成为一个方法 // 异步方法 fs.writeFile(path,data,callback) // 文件不存在 建立;若存在,则删除再建立 // path 路径/文件名 // data 文件的数据 // callback(error) 回调函数 fs.writeFile("./newdir01/a.txt","这是一个写入的字符串ssssss",(error)=>{ console.log(error); });
2.2 文件的删除(取消硬链接)(具备权限)
// 文件的删除 const fs = require("fs"); try { fs.unlinkSync("./文件夹/a.txt"); } catch (error) { console.log(error.message); }
2.3 文件的读取
// 文件的读取 const fs = require("fs"); try { //读取指定文件内容(二进制文件的十六进制形式) let data = fs.readFileSync("./newdir01/a.txt"); console.log(data);//buffer console.log(data.toString());//转成字符串 //将newdir01/a.txt文件内容写入 222.txt fs.writeFileSync("./222.txt",data); } catch (error) { console.log("文件读取失败"+error.message); }
运行代码后,除了建立了222.txt文件,控制台还输出如下结果:
fs.readFileSync( ) 方法也能够读取图片,将读取到的数据经过 fs.writeFileSync("图片名.扩展名",data),也能够实现图片的复制。
2.4 文件的追加(文本文件)
// 文本文件的内容追加 const fs = require("fs"); fs.appendFile("./011.txt","追加新的字符串",(error)=>{ console.log(error); });
· file参数就是已经存在的文件路径
· 若是文件不存在,会自动建立一个新的文本文件
2.5 文件的修改
与文件夹的修改相同。
Node.js的 fs 文件系统暂时先说到这里,这里有三个小练习:
1. 打印出指定文件夹下的全部文件和文件夹(包括子文件夹中的全部文件和文件夹,依次层层进入,读取全部);
2. 打印出指定文件夹下的因此 “.txt” 文件夹;
3. 给定目录,建立文件夹。
咱们在 2.3文件的读取 中提到 Buffer的概念。那么Buffer究竟是什么呢?能够参考下一篇博客。
学完本篇博客后,你能不能实现我在上一篇博客结尾处提到的在http服务的响应中引入HTML文件呢?
这里有一种比较原始的方法:我这里的思路是触发事件后,在响应代码处,先读取指定的 .html 文件获得返回数据data,而后使用 response.write( data )响应写出数据。
// 定义登陆页面 emitter.on("/showLogin",function(req,res){ console.log("showLogin 页面"); try { let data = fs.readFileSync("./01.html"); res.write(data) } catch (error) { console.log("文件读取失败"+error.message); } res.end(); });
能够实现 .html 文件的读取操做。可是,实际开发过程当中不建议这种方法。