02-fs 模塊

fs 模塊

fs 全稱為 file system ,稱之為 文件系統(tǒng) ,是 Node.js 中的 內(nèi)置模塊 ,可以對計(jì)算機(jī)中的磁盤進(jìn)行操作。

本章節(jié)會(huì)介紹如下幾個(gè)操作:

  1. 文件寫入

  2. 文件讀取

  3. 文件移動(dòng)與重命名

  4. 文件刪除

  5. 文件夾操作

  6. 查看資源狀態(tài)

文件寫入

文件寫入就是將 <span style="color:red">數(shù)據(jù)</span> 保存到 <span style="color:red">文件</span> 中,我們可以使用如下幾個(gè)方法來實(shí)現(xiàn)該效果

方法 說明
writeFile 異步寫入
writeFileSync 同步寫入
appendFile / appendFileSync 追加寫入
createWriteStream 流式寫入

writeFile 異步寫入

語法fs.writeFile(file, data[, options], callback)

參數(shù)說明

  • file 文件名

  • data 待寫入的數(shù)據(jù)

  • options 選項(xiàng)設(shè)置 (可選)

  • callback 寫入回調(diào)

返回值undefined

代碼示例

// require 是 Node.js 環(huán)境中的 '全局' 變量,用來導(dǎo)入模塊
const fs = require('fs')

// 將 [三人行,必有我?guī)熝?。] 寫入到當(dāng)前文件夾下的 [座右銘.txt] 文件中
fs.writeFile('./座右銘.txt', '三人行,必有我?guī)熝伞?, err =>{
    // 如果寫入失敗,則回調(diào)函數(shù)調(diào)用時(shí),會(huì)傳入錯(cuò)誤對象,如寫入成功,會(huì)傳入 null
    if(err){
        console.log(err)
        return
    }
    console.log('寫入成功')  
})

writeFileSync 同步寫入

語法: fs.writeFileSync(file, data[, options])

參數(shù)與 fs.writeFile 大體一致,只是沒有 callback 參數(shù)

返回值:undefined

代碼示例:

try{
    fs.writeFileSync('./座右銘.txt', '三人行,必有我?guī)熝伞?)
}catch(e){
    console.log(e)
}

Node.js 中的磁盤操作是由其他 線程 完成的,結(jié)果的處理有兩種模式:

  • 同步處理 JavaScript 主線程 會(huì)等待 其線程的執(zhí)行結(jié)果,然后再繼續(xù)執(zhí)行主線程的代碼,效率較低
  • 異步處理 JavaScript 主線程 不會(huì)等待 其線程的執(zhí)行結(jié)果,直接執(zhí)行后續(xù)的主線程代碼,效率較好

appendFile / appendFileSync 追加寫入

appendFile 作用是在文件尾部追加內(nèi)容,appendFile 語法與 writeFile 語法完全相同

語法:

fs.appendFile(file, data[, options], callback)

fs.appendFileSync(file, data[, options])

返回值:二者都為 undefined

實(shí)例代碼:

fs.append('./座右銘.txt', '則其善者而從之,其不善者而改之。', err =>{
    if(err) throw err
    console.log('追加成功')
})

fs.appendFileSync('./座右銘.txt','\r\n溫故而知新,可以為師矣')

createWriteStream 流式寫入

語法fs.createWriteStream(path[, options])

參數(shù)說明

  • path 文件路徑

  • options 選項(xiàng)配置( 可選

**返回值: **Object

代碼示例:

let ws = fs.createWriteStream('./觀書有感.txt')

//寫入數(shù)據(jù)到流
ws.write('半畝方塘一鑒開\r\n')
ws.write('天光云影共徘徊\r\n')
ws.write('問渠那得清如許\r\n')
ws.write('為有源頭活水來\r\n')

//關(guān)閉寫入流,表明已沒有數(shù)據(jù)要被寫入可寫流
ws.end()

<span style="color:red">程序打開一個(gè)文件是需要消耗資源的</span>,流式寫入可以減少打開關(guān)閉文件的次數(shù)。

流式寫入方式適用于 <span style="color:red">大文件寫入或者頻繁寫入</span>的場景,writeFile適合于 <span style="color:red">寫入頻率較低的場景</span>

寫入文件的場景

文件寫入 在計(jì)算機(jī)中是一個(gè)非常常見的操作,下面的場景都用到了文件寫入

  • 下載文件

  • 安裝軟件

  • 保存程序日志,如 Git

  • 編輯器保存文件

  • 視頻錄制

當(dāng) <span style="color:red">需要持久化保存數(shù)據(jù)</span> 的時(shí)候,應(yīng)該想到 文件寫入

文件讀取

文件讀取顧名思義,就是通過程序從文件中取出其中的數(shù)據(jù),我們可以使用如下幾種方式:

方法 說明
readFile 異步讀取
readFileSync 同步讀取
createReadStream 流式讀取

readFile 異步讀取

語法: fs.readFile(path[, options], callback)

參數(shù)說明

  • path 文件路徑

  • options 選項(xiàng)配置

  • callback 回調(diào)函數(shù)

返 回 值 : undefined

代碼示例:

// 導(dǎo)入 fs 模塊

fs.readFile('./座右銘.txt', (error,data) =>{
    if(err) throw err
    console.log(data)
})

fs.readFile('./座右銘.txt', 'uft-8', (error,data) =>{
    if(err) throw err
    console.log(data)
})

readFileSync 同步讀取

語法:fs.readFileSync(path[, options])

參數(shù)說明:

  • path 文件路徑

  • options 選項(xiàng)配置

返 回 值 :string | Buffer

代碼示例:

let data = fs.readFileSync('./座右銘.txt')
let data = fs.readFileSync('./座右銘.txt', 'utf-8')

createReadStream 流式讀取

語法:fs.createReadStream(path[, options])

參數(shù)說明:

  • path 文件路徑

  • options 選項(xiàng)配置( 可選

返回值:Object

代碼示例:

// 創(chuàng)建讀取流對象
let rs = fs.createReadStream('./觀書有感.txt')

// 每次取出 64k 數(shù)據(jù)后執(zhí)行一次 data 回調(diào)
// 綁定一個(gè) data 事件  chunk 塊兒  大塊兒
re.on('data', chunk =>{
    console.log(chunk)
    console.log(chunk.length)
})

// 讀取完畢后,執(zhí)行 end 回調(diào) (可選事件)
re.on('end', () =>{
    console.log('讀取完畢')
})

讀取文件應(yīng)用場景

  • 電腦開機(jī)

  • 程序運(yùn)行

  • 編輯器打開文件

  • 查看圖片

  • 播放視頻

  • 播放音樂

  • Git 查看日志

  • 上傳文件

  • 查看聊天記錄

文件移動(dòng)與重命名

在 Node.js 中,我們可以使用 renamerenameSync 來移動(dòng)或重命名 文件或文件夾

語法:

fs.rename(oldPath, newPath, callback)

fs.renameSync(oldPath, newPath)

參數(shù)說明:

  • oldPath 文件當(dāng)前的路徑

  • newPath 文件新的路徑

  • callback 操作后的回調(diào)

代碼示例:

fs.rename('./觀書有感.txt', './論語/觀書有感.txt', err =>{
    if(err) throw err
    console.log('移動(dòng)完成')
})

fs.renameSync('./座右銘.txt', './論語/.我的座右銘.txt')

: 如果還是移動(dòng)到當(dāng)前路徑,但是修改了名字,就是重命名了

文件刪除

在 Node.js 中,我們可以使用 unlinkunlinkSync 來刪除文件

語法:

fs.unlink(path, callback)

fs.unlinkSync(path)

參數(shù)說明

  • path 文件路徑

  • callback 操作后的回調(diào)

代碼示例:

const fs = require('fs')

fs.unlink('./test.txt', err =>{
    if(err) throw err
    console.log('刪除成功')
})

fs.unlinkSync('./test2.txt')


// 調(diào)用 rm 方法  14.4   同步 rmSync
fs.rm('./論語.txt', err => {
  if (err) {
    console.log('刪除失敗')
    return

  }
  console.log('刪除成功')
})

文件夾操作

借助 Node.js 的能力,我們可以對文件夾進(jìn)行 創(chuàng)建 、讀取刪除 等操作

方法 說明
mkdir / mkdirSync 創(chuàng)建文件夾
readdir / readdirSync 讀取文件夾
rmdir / rmdirSync 刪除文件夾

mkdir 創(chuàng)建文件夾

在 Node.js 中,我們可以使用 mkdirmkdirSync 來創(chuàng)建文件夾

語法:

fs.mkdir(path[, options], callback)

fs.mkdirSync(path[, options])

參數(shù)說明

  • path 文件夾路徑

  • options 選項(xiàng)配置( 可選

  • callback 操作后的回調(diào)

示例代碼:

// 異步創(chuàng)建文件夾  mk  make  制作   dir  directory  文件夾
fs.mkdir('./page', err =>{
    if(err) throw err
    console.log('創(chuàng)建成功')
})

// 遞歸異步創(chuàng)建
fs.mkdir('./1/2/3', {recursive: true}, err =>{
    if(err) throw err
    console.log('遞歸創(chuàng)建成功')
})

// 遞歸同步創(chuàng)建文件夾
fs.mkdirSync('./x/y/z', {recursive: true})

readdir 讀取文件夾

在 Node.js 中,我們可以使用 readdirreaddirSync 來讀取文件夾

語法:

fs.readdir(path[, options], callback)

fs.readdirSync(path[, options])

參數(shù)說明:

  • path 文件夾路徑

  • options 選項(xiàng)配置( 可選

  • callback 操作后的回調(diào)

示例代碼:

// 異步讀取
fs.readdir('./論語', (err, data) => {
    if(err) throw err
    console.log(data)
})
// 同步讀取 
let data = fs.readdirSync('./論語')
console.log(data)

rmdir 刪除文件夾

在 Node.js 中,我們可以使用 rmdirrmdirSync 來刪除文件夾

語法

fs.rmdir(path[, options], callback)

fs.redirSync(path[, options])

參數(shù)說明

  • path 文件夾路徑

  • options 選項(xiàng)配置( 可選 )

  • callback 操作后的回調(diào)

示例代碼:

// 異步刪除文件夾  rm  remove 移除
fs.rmdir('./page', err => {
    if(err) throw err
    console.log('刪除成功')
})
//異步遞歸刪除文件夾  不推薦
//=>DeprecationWarning: In future versions of Node.js, fs.rmdir(path, { recursive: true }) will be removed. Use fs.rm(path, { recursive: true }) instead
fs.rmdirSync('./1', {recursive: true}, err => {
    if(err){ 
        console.log(err)
        return
    }
    console.log('遞歸刪除')
})
//同步遞歸刪除文件夾
fs.rmdirSync('./x', {recursive: true})

// 建議使用
fs.rm('./a', { recursive: true }, err => {
  if (err) {
    console.log(err)
    return
  }
  console.log('刪除成功')
})

查看資源狀態(tài)

在 Node.js 中,我們可以使用 statstatSync 來查看資源的詳細(xì)信息

語法

fs.stat(path[, options], callback)

fs.statSync(path[, options])

參數(shù)說明

  • path 文件夾路徑

  • options 選項(xiàng)配置( 可選 )

  • callback 操作后的回調(diào)

示例代碼:

// 異步獲取狀態(tài)
// stat  方法  status 縮寫 狀態(tài)
fs.stat('/data.txt', (err, data) =>{
    if(err) throw err
    console.log(data)
})
// 同步獲取狀態(tài)
let data = fs.statSync('./data.txt')
3d5f0b54415a2949c04dcbc49a0452e7ec91899b.png

結(jié)果值對象結(jié)構(gòu)

  • size 文件體積

  • birthtime 創(chuàng)建時(shí)間

  • mtime 最后修改時(shí)間

  • isFile 檢測是否為文件

  • isDirectory 檢測是否為文件夾

  • ....

相對路徑問題

fs 模塊對資源進(jìn)行操作時(shí),路徑的寫法有兩種:

  • 相對路徑

    • ./座右銘.txt 當(dāng)前目錄下的 座右銘.txt
    • 座右銘.txt 等效于上面的寫法
    • ../座右銘.txt 當(dāng)前目錄的上一級目錄中的 座右銘.txt
  • 絕對路徑

    • D:/Program Files windows 系統(tǒng)下的絕對路徑
    • /user/bin Linux 系統(tǒng)下的絕對路徑

相對路徑中所謂的 當(dāng)前目錄 ,指的是 命名行的工作目錄 ,而并非是文件的所在目錄

所以當(dāng)命名行的工作目錄與文件所在目錄不一致時(shí),會(huì)出現(xiàn)一些 Bug

__dirname

__dirnamerequire 類似,都是 Node.js 環(huán)境中的 '全局' 變量

__dirname 保存著 <span style="color:red">當(dāng)前文件夾所在目錄的絕對路徑</span>,可以使用 __dirname 與文件名拼接成絕對路徑

代碼示例:

//=>__dirname + '/data.txt'  === 'D:\\Desktop\\Node\\code\\03-fs模塊/data.txt'
let data = fs.readFileSync(__dirname + '/data.txt')
console.log(data) 

使用 fs 模塊的時(shí)候,盡量使用 __dirname 路徑轉(zhuǎn)換為絕對路徑,這樣可以避免相對路徑產(chǎn)生的 Bug

練習(xí)

編寫一個(gè) JS 文件,實(shí)現(xiàn)復(fù)制文件的功能

/* 
 *  需求:
 *    復(fù)制  資料文件夾下的  [笑看風(fēng)云.mp4]
 */
// 導(dǎo)入 fs 模塊
const fs = require('fs')
// 方式一  readFile
// 讀取文件內(nèi)容
let data = fs.readFileSync('./資料/笑看風(fēng)云.mp4')
// 寫入文件
fs.writeFileSync('./資料/笑看風(fēng)云2.mp4', data)

// 方式二 流式操作
// 創(chuàng)建讀取流對象
const rs = fs.createReadStream('./資料/笑看風(fēng)云.mp4')
// 創(chuàng)建一個(gè)寫入流對象
const ws = fs.createWriteStream('./資料/笑看風(fēng)云3.mp4')

// 綁定data事件
// 理想狀態(tài)下,讀取 64k 就寫入 64 k,這樣消耗的內(nèi)存最少,實(shí)際上讀取的速度大于寫入的速度
rs.on('data', chunk => {
   ws.write(chunk)
})
//  綁定data事件 ==== rs.pipe(ws)

文件重命名

// 1. 導(dǎo)入 fs 模塊
const fs = require('fs')

// 讀取 03-fs模塊 文件夾
const files = fs.readdirSync('../03-fs模塊')

// 遍歷數(shù)組
files.forEach(item => {
  // 判斷
  let [num, name] = item.split('-')
  if (num < 10) {
    num = '0' + num
  }
  // 創(chuàng)建新的文件名
  let newName = num + '-' + name
  // 重命名
  fs.renameSync(`../03-fs模塊/${item}`, `../03-fs模塊/${newName}`)
})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容