Node.js的文件系統

Node.js的文件系統

JavaScript的是沒有操作文件的能力,但是Node.js是可以做到的。
Node.js提供了操作文件的接口,但是接口有太多。主要使用一些常用的接口。

文件系統模塊是一個封裝了標準的 POSIX 文件 I/O 操作的集合。通過 require('fs') 使用這個模塊。所有的方法都有同步和異步兩種模式。

Node.js的文件系統API

1.讀取文件
Node.js提供了兩種方式讀取文件,一個是異步的方式讀取文件,一個是同步的方式讀取文件。


var fs = require("fs");
// 我們來定義一個函數,用來讀取文件
function readFile (fileUrl) {
  console.log("--開始讀取--");
  fs.readfile(fileUrl,function(err,data){
    if(err){
      console.log("--讀取失敗--")
    }
    console.log("讀取到的數據是:"+data.toString());
  })
}
readFile("./src/test.txt");
// 執行函數,就能讀取到文件的信息
// 上邊是異步讀取數據,同步讀取數據是
// 同步讀取函數
function readFileSync(fileUrl) {
    console.log("----開始同步讀取----");
    var data = fs.readFileSync(fileUrl);
    console.log("同步讀取的數據是" + data.toString());
    console.log("----讀取結束----")
}
readFileSync("./src/test.txt");
// 推薦使用異步讀取數據,速度快,性能好,不會阻塞;

2.寫入文件

// fs.writeFile(filename,data,[options],callback);
/**
 * filename, 必選參數,文件名
 * data, 寫入的數據,可以字符或一個Buffer對象
 * [options],flag,mode(權限),encoding,都是選填
 * callback 讀取文件后的回調函數,參數默認err
 */
// 寫文件
var w_data = "我是寫入的內容";
fs.writeFile("./src/test.txt",w_data,function (err) {
  if (err) {
    console.error(err);
  }
  console.log("寫入成功")
})
// 有一點不得不提,就是如果你寫入的文件是已經存在的文件,那么之前的內容會被覆蓋掉。
// 下邊的方法就是把你寫入內容追加到原來的文件中;

3.追加內容


// fs.appendFile(filename,data,[options],callback)
/**
 * filename,必填參數,文件名
 * data,追加的內容
 * options,選填,flag,mode。。。
 * callback,默認參數err
 */
// 追加內容
var appendData = "我是被追加的內容";
fs.appendFile("./src/test.txt",appendData,function (err) {
  if (err) {
    console.error(err);
  }
  console.log("追加內容成功!")
})

4.關于打開文件,讀取文件, 截取文件,寫入文件,關閉文件,

4.1 先來看看打開文件

fs.open(filename,flag,[mode],callback)
參數說明
/**
 * filename,必填參數
 * flags,必填參數,詳細參考這些參數設置
 * mode,選填,設置權限
 * callback,默認參數第一個err,第二個fd,這個fd是個啥玩意,解釋如下
 * fd為一個整數,表示打開文件返回的文件描述符,window中又稱文件句柄
 */
/*Flag  描述
r   以讀取模式打開文件。如果文件不存在拋出異常。
r+  以讀寫模式打開文件。如果文件不存在拋出異常。
rs  以同步的方式讀取文件。
rs+ 以同步的方式讀取和寫入文件。
w   以寫入模式打開文件,如果文件不存在則創建。
wx  類似 'w',但是如果文件路徑存在,則文件寫入失敗。
w+  以讀寫模式打開文件,如果文件不存在則創建。
wx+ 類似 'w+', 但是如果文件路徑存在,則文件讀寫失敗。
a   以追加模式打開文件,如果文件不存在則創建。
ax  類似 'a', 但是如果文件路徑存在,則文件追加失敗。
a+  以讀取追加模式打開文件,如果文件不存在則創建。
ax+ 類似 'a+', 但是如果文件路徑存在,則文件讀取追加失敗。
*/

一個實例寫法:

fs.open("./src/test.txt","r+",function (err,fd) {
  if (err) {
    console.error(err);
  }
  console.log(fd)// fd 是一個windows系統的句柄,類似于給文件一個標識,后邊會用到
  // 還記得定時器么,瀏覽器就會給每個定時器一個id,我們每次清除定時器,就是清除對應id的定時器
  console.log("文件被打開了")
  // 文件被打開,但是,是在內存中打開的,你根本看不到的,不用在這做糾結。
})

4.2 讀取文件
文件被打開了,那么我肯定是要讀取的呀!

file.read(filename,buffer,offset,length,position,callback)
/**
 * fd, 使用fs.open打開成功后返回的文件描述符
 * buffer, 一個Buffer對象,v8引擎分配的一段內存
 * offset, 整數,向緩存區中寫入時的初始位置,以字節為單位
 * length, 整數,讀取文件的長度
 * position, 整數,讀取文件初始位置;文件大小以字節為單位
 * callback(err, bytesRead, buffer), 讀取執行完成后回調函數,bytesRead實際讀取字節數,被讀取的緩存區對象
 */
 

讀取文件的實例:

fs.open("./src/test.txt","r+",function (err,fd) {
    if (err) {
        console.error(err)
    }
    console.log("文件被打開了")
    console.log("準備讀取文件");
    var buffer = new Buffer(1024);
    // fd 在read的時候用到了,其實類似于一個文件的標識
    fs.read(fd,buffer,0,buffer.length,0,function (err,bytesRead,buffer) {
        if (err) {
            console.error(err)
        }
        console.log(bytesRead+" 字節被讀")
        if (bytesRead>0) {
            console.log("讀取的內容"+buffer.toString())
        }
    })
})

4.3 截取文件

fs.// fs.ftruncate(fd,len,callback)
/**
 * fd,打開文件時候的fd
 * len,要截取的長度
 * callback,回調函數,沒有參數
 */
 

截取文件實例,截取完成后關閉文件:

// 這是一套,打開文件,截取文件,讀取文件,最后關閉文件
fs.open("./src/test.txt","r+",function (err,fd) {
    if (err) {
        console.log(err)
    }
    console.log("打開文件成功!")
    console.log("準備截取文件");
    // 也就是說,文件被截取之后,能讀到的就是被截取的部分
    fs.ftruncate(fd,10,function (err) {
        if (err) {
            console.log(err)
        }
        console.log("截取文件成功!");
        console.log("開始讀取文件");
        fs.read(fd,buffer,0,buffer.length,0,function (err,bytesRead) {
            if (err) {
                console.error(err)
            }
            console.log(bytesRead+" 字節被讀取");
            if (bytesRead>0) {
                console.log(buffer.slice(0,bytesRead).toString())
            }
            // 關閉文件
            fs.close(fd,function (err) {
                if (err) {
                    console.log(err)
                }
                console.log("文件關閉")
            })
        })
    })
})
文件被截取之后,能讀到就是被截取的部分

4.4 關閉文件
具體用法,如上例所示

fs.close(fd,callback)
/**
 * fd,打開文件時候的fd
 * callback,回調函數,參數err
 */
 

4.5 寫入文件

// fs.write(fd,buffer,offset,length,position,callback);
/**
 * fd, 使用fs.open打開成功后返回的文件描述符
 * buffer, 一個Buffer對象,v8引擎分配的一段內存
 * offset, 整數,從緩存區中讀取時的初始位置,以字節為單位
 * length, 整數,從緩存區中讀取數據的字節數
 * position, 整數,寫入文件初始位置;
 * callback(err, written, buffer), 寫入操作執行完成后回調函數,written實際寫入字節數,buffer被讀取的緩存區對象
 */

寫入文件實例:

fs.open("./src/test.txt","r+",function (err,fd) {
    if (err) {
        console.error(err)
    }
    console.log("文件被打開了");
    console.log("準備寫入文件");
    var buf = new Buffer("寫入的內容");
    fs.write(fd,buf,0,buf.length,0,function (err,written,buffer) {
        if (err) {
            console.error(err)
        }
        // 寫入文件的字符數,一個中文,utf8編碼三個字節
        console.log(written);
        // 我們會發現之前的text.txt文件被改寫了
        console.log(buffer.toString())
    })
    fs.close(fd,function (err) {
        if (err) {
            console.error(err)
        }
        console.log("文件被關閉了")
    })
})

5.獲取文件信息

// fs.stat(filename,callback)
/**
 * filename,必填參數,文件路徑和文件名稱
 * callback,第一個參數err,第二個stats,返回一個文件相關的信息
 */
 

獲取文件信息實例:

fs.stat(__dirname+"/test.txt",function (err,stats) {
    if (err) {
        console.error(err)
    }
    console.log(stats)
})

6.創建文件夾


// fs.mkdir(filname,callback)
/**
 * filename,必填參數
 * callback,只有一個err參數
 */
 
 fs.mkdir(__dirname+"/test/",function (err) {
    if (err) {
        console.error(err)
    }
    console.log("文件夾創建成功!")
})

7.讀取文件夾

// fs.readdir(filename,{options},callback)
/**
 * filename,必填參數
 * options,選填參數
 * callback,第一個參數err,第二個參數files,返回的是一個文件的數組
 */
 

讀取文件夾實例:


// 我們在剛才創建的test文件夾下,添加兩個文件看看,一個是index.js,index.html
fs.readdir(__dirname+"/test",function (err,files) {
    if (err) {
        console.error(err)
    }
    console.log("讀取文件夾成功!")
    console.log(files)
    files.forEach(function (value,index) {
        console.log(value+"---"+index)
    })
})

8.刪除文件

// fs.unlink(filename,callback)
/**
 * filename,必填參數
 * callback,參數err
 */

刪除文件的實例:


// 在新建的test文件夾內在新建一個index.txt文件,然后我們再把它刪掉
fs.unlink(__dirname+"/test/index.txt",function (err) {
    if (err) {
        console.error(err)
    }
    console.log("刪除成功!")
})

9.刪除文件夾

fs.rmdir(fliename,callback);
/**
 * filename,必填參數
 * callback,參數err
 */
 
// 清空文件夾,同步操作
function cleanDir(filename) {
    // 采用同步的方式讀目標文件夾,獲取files對象
    var files = fs.readdirSync(filename);
    // 遍歷files對象,直接forEach了
    files.forEach((item) => {
        var stats = fs.statSync(filename+"/"+item);
        // 判斷當前是文件還是文件夾
        if (stats.isDirectory()) {
            // 如果是文件夾就重復調用方法
            cleanDir(filename+"/"+item)
        }else{
            // 如果不是文件夾,那就是文件,直接刪除
            fs.unlinkSync(filename+"/"+item);
            console.log("刪除文件"+filename+"/"+item+"成功")
        }
    })
}

// 刪除每個空文件夾,同步操作
function deleteDir(filename) {
    // 同步方式讀取文件夾,得到files
    var files = fs.readdirSync(filename);
    // 判斷files下是否存在別的文件夾,也就是判斷length
    if (files.length>0) {
        var tempFile = 0;
        files.forEach((item) => {
            tempFile++;
            deleteDir(filename+"/"+item);
        })
        // 如果把子文件夾都刪除了,那么母文件夾的filename和上述的不同,需要單獨列出來,
        // 做一步判斷,然后刪除母文件夾
        if (tempFile==files.length) {
            fs.rmdirSync(filename)
            console.log("刪除文件夾"+filename+"成功")
        }
    }else{
        fs.rmdirSync(filename)
        console.log("刪除文件夾"+filename+"成功")
    }
}
cleanDir(__dirname + "/test");
deleteDir(__dirname + "/test");

基本上Node.js的文件系統最常用的api,大體都接觸了一遍。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,786評論 18 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,722評論 18 399
  • Node.js是目前非常火熱的技術,但是它的誕生經歷卻很奇特。 眾所周知,在Netscape設計出JavaScri...
    w_zhuan閱讀 3,629評論 2 41
  • Node.js是目前非常火熱的技術,但是它的誕生經歷卻很奇特。 眾所周知,在Netscape設計出JavaScri...
    Myselfyan閱讀 4,082評論 2 58
  • 剛認識了一位新朋友,說是朋友,其實她是客戶,因為在工作聊得很投機,也就算是一個新朋友吧! 第一次見到她是在11月左...
    郭顏閱讀 253評論 0 0