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 文件的讀取操做。可是,實際開發過程當中不建議這種方法。