1. 程式人生 > 實用技巧 >Node.js中的fs模組的使用

Node.js中的fs模組的使用

JavaScript的是沒有操作檔案的能力,但是 Node 是可以做到的,Node 提供了操作檔案系統模組,是 Node 中使用非常重要和高頻的模組,是絕對要掌握的一個模組系統。

fs模組提供了非常多的介面,這裡主要說一下一些常用的介面。

1.常用API快速複習

fs.stat檢測是檔案還是目錄

const fs = require('fs')
fs.stat('hello.js', (error,stats)=>{
    if(error) {
        console.log(error)
    } else {
        console.log(stats)
        console.log(`檔案:${stats.isFile()}`)
        console.log(`目錄:${stats.isDirectory()}`)
    }
})

fs.mkdir建立目錄

const fs = require('fs')
fs.mkdir('logs', error => {
    if(error) {
        console.log(error)
    } else {
        console.log('目錄建立成功!')
    }
})

fs.rmdir刪除目錄

const fs = require('fs')
fs.rmdir('logs', error => {
    if(error) {
        console.log(error)
    } else {
        console.log('成功刪除了目錄 logs')
    }
})

fs.writeFile建立寫入檔案

const fs = require('fs')
fs.writeFile('logs/hello.log','您好~\n', error => {
    if(error) {
        console.log(error)
    } else {
        console.log('成功寫入檔案');
    }
})

fs.appendFile追加檔案

const fs = require('fs')
fs.appendFile('logs/hello.log','hello~\n', error => {
    if(error) {
        console.log(error)
    } else {
        console.log('成功寫入檔案');
    }
})

fs.readFile讀取檔案

const fs = require('fs')
fs.readFile('logs/hello.log','utf-8', (error, data) => {
    if(error) {
        console.log(error)
    } else {
        console.log(data);
    }
})

fs.unlink刪除檔案

const fs = require('fs')
fs.unlink(`logs/${file}`, error => {
    if(error) {
        console.log(error)
    } else {
        console.log(`成功刪除了檔案: ${file}`)
    }
})

fs.readdir讀取目錄

const fs = require('fs')
fs.readdir('logs', (error, files) => {
    if(error) {
        console.log(error)
    } else {
        console.log(files);
    }
})

fs.rename重新命名,還可以更改檔案的存放路徑

const fs = require('fs')
fs.rename('js/hello.log', 'js/greeting.log', error => {
    if(error) {
        console.log(error)
    } else {
        console.log('重新命名成功')
    }
})

2.第三方npm包 mkdirp 的使用

mkdirp不僅可以建立資料夾,還可以建立多層的資料夾,類似mkdir -p命令

midir -ptmp/foo/bar/baz

上述命令也可以在當前目錄建立多層幾資料夾。

如下程式碼在當前目錄生成多層級資料夾

const mkdirp = require('mkdirp')
mkdirp('tmp/foo/bar/baz').then(made => console.log(`建立目錄於: ${made}`))
// 建立目錄於: /Users/zhangbing/github/CodeTest/Node/fs/tmp

3.實戰舉例

實戰1

判斷伺服器上面有沒有 upload 目錄。如果沒有就建立這個目錄,如果有的話不做操作

const fs = require('fs')

const path = './upload'
fs.stat(path, (err, data) => {
    if(err) {
        // 執行建立目錄
        mkdir(path)
        return
    }
    if(data.isDirectory()) {
        console.log('upload目錄存在');
    }else{
        // 首先刪除檔案,再去執行建立目錄
        fs.unlink(path, err => {
            if(!err) {
                mkdir(path)
            }
        })
    }
})

function mkdir(dir) {
    fs.mkdir(dir, err => {
        if(err) {
            console.log(err);
            return
        }
    })
}

實戰2

wwwroot 資料夾下面有 imagescssjs 以及 index.html, 找出 wwwroot 目錄下面的所有的目錄,然後放在一個數組中

使用同步方法方式

const fs = require('fs')
const path = './wwwroot'
const dirArr = []

const dirs = fs.readdirSync(path)
dirs.forEach(item => {
    if(fs.statSync(path + '/' + item).isDirectory()) {
        dirArr.push(item)
    }
})
console.log('dirArr', dirArr)
// dirArr [ 'css', 'images', 'js' ]

使用 async/await 方式

const fs = require('fs')
const path = './wwwroot'
const dirArr = []

function isDir(path) {
    return new Promise((resolve, reject) => {
        fs.stat(path, (error, stats) => {
            if(error) {
                console.log(error)
                reject(error)
                return
            }
            if(stats.isDirectory()) {
                resolve(true)
            } else {
                resolve(false)
            }
        })
    })
}

function main(){
    fs.readdir(path, async (error, data) => {
        if(error) {
            console.log(error)
            return
        } else {
            for(let i = 0; i < data.length; i++) {
                if(await isDir(path + '/' + data[i])) {
                    dirArr.push(data[i])
                }
            }
            console.log('dirArr', dirArr)
        }
    })
}

main() // dirArr [ 'css', 'images', 'js' ]

4.管道流

管道提供了一個輸出流到輸入流的機制。通常我們用於從一個流中獲取資料並將資料傳遞到另外一個流中。以下例項我們通過讀取一個檔案內容並將內容寫入到另外一個檔案中。

const fs = require("fs")
//建立一個可讀流
const readerStream = fs.createReadStream('input.txt')
//建立一個可寫流
const writerStream = fs.createWriteStream('output.txt')
//管道讀寫操作
//讀取input.txt檔案內容,並將內容寫入到output.txt檔案中
readerStream.pipe(writerStream)
console.log("程式執行完畢")

fs.createReadStream從檔案流中讀取資料

const fs = require('fs')
const fileReadStream = fs.fileReadStream('demo1.js')
let count = 0
let str = ''
fileReadStream.on('data', chunk => {
    console.log(`${++count}接收到:${chunk.length}`)
    str += chunk
})
fileReadStream.on('end', () => {
    console.log('---結束---')
    console.log(count + ',' + star)
})
fileReadStream.on('error', error => {
    console.log(error)
})

fs.createWriteStream寫入檔案

const fs = require("fs")
const data ='我是從資料庫獲取的資料,我要儲存起來'
//建立一個可以寫入的流,寫入到檔案output.txt中
const writerStream = fs.createWriteStream('output.txt')
//使用utf8編碼寫入資料
writerStream.write(data,'UTF8')
//標記檔案末尾
writerStream.end()
//處理流事件-->finish事件
writerStream.on('finish', () => {
    /*finish-所有資料已被寫入到底層系統時觸發。*/
    console.log("寫入完成。")
})
writerStream.on('error', err => {
    console.log(err.stack);
})
console.log("程式執行完畢")

東莞vi設計https://www.houdianzi.com/dgvi/ 豌豆資源網站大全https://55wd.com

實戰:複製圖片

在專案根目錄有一張圖片2020.png,把它複製到/wwwroot/images中

程式碼如下

const fs = require("fs")

const readStream = fs.createReadStream('./2020.png')
const writeStream = fs.createWriteStream('./wwwroot/images/2021.png')

readStream.pipe(writeStream)

需要特別注意的是,fs.createWriteStream要寫入的目錄一定要帶上要複製的檔名,也就是不能寫成fs.createWriteStream('./wwwroot/images/')否則在 macOS 下會報如下錯誤:

Error:EISDIR: illegal operation on a directory, open <directory>