node.js 17 文件操作

本文參考原文-http://bjbsair.com/2020-03-22/tech-info/2819.html
在講完了模塊概念后,這一篇我們看一下node.js中的文件操作。文件操作的API在fs模塊中,fs全稱為 "File System"。

絕大部分編程語言都會(huì)提供文件操作功能,node.js也不例外。下面我們主要看一下文件/目錄的判斷,文件的新增,刪除,讀取,寫入,重命名和拷貝等。

node.js 07 文件操作

node.js 文件操作

node.js有一個(gè)很大的特點(diǎn),就是異步操作。這一點(diǎn)在文件操作中也一樣。有些語言判斷文件還是目錄不會(huì)使用異步,但是node.js不一樣,使用異步,通過回調(diào)函數(shù)進(jìn)行處理。

所以學(xué)習(xí)node.js一定要有異步的概念,回調(diào)函數(shù)也是必須要理解的。后面會(huì)有關(guān)于異步處理的專門講解。

如何判斷傳入路徑為文件還是目錄

首先需要引入fs模塊,然后通過fs.stat方法中的回調(diào)函數(shù)進(jìn)行判斷對(duì)象是文件還是目錄。

看一下示例代碼,個(gè)人一直認(rèn)為寫代碼不寫注釋就是拒絕團(tuán)隊(duì)合作,拒絕知識(shí)共享。

//1. 引入fs模塊  
const fs = require('fs');  
  
//2. 調(diào)用fs.stat方法,傳入文件,通過回調(diào)函數(shù)處理data對(duì)象  
fs.stat('./package.json', (err,data)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
      
    //3. 調(diào)用 isFile()方法判斷是否為文件  
    console.log(`is file: ${data.isFile()}`)  
    //4. 調(diào)用 isDirectory()方法判斷是否為目錄  
    console.log(`is directory: ${data.isDirectory()}`)  
})

由于package.json是一個(gè)文件,所以打印輸出時(shí)isFile:true。輸出結(jié)果如下:

D:\Projects\nodejs\NodeDemo>node app.js  
  
is file: true  
  
is directory: false

創(chuàng)建目錄

同樣需要引入"fs"模塊。由于所有的文件操作都需要引入"fs"模塊,后面的示例將不再強(qiáng)調(diào)。然后調(diào)用fs.mkdir()方法進(jìn)行創(chuàng)建。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 調(diào)用mkdir()方法創(chuàng)建目錄  
fs.mkdir('./testDir', (err)=>{  
    if(err){  
        console.log(err);  
        return;  
    }  
    console.log('創(chuàng)建目錄完成')  
})

創(chuàng)建文件并寫入文件

在創(chuàng)建文件時(shí)可以通過方法fs.writeFile()直接創(chuàng)建,并寫入內(nèi)容。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 創(chuàng)建并寫入文件  
fs.writeFile('./test.txt','Hello, node.js', (err)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('創(chuàng)建寫入文件成功')  
})

上面的代碼示例創(chuàng)建了文件test.txt,并在文件中寫入了"Hello, node.js"。

添加文件內(nèi)容

如果只是在創(chuàng)建的時(shí)候?qū)懭胛募?nèi)容肯定是不夠的,任何處理文件的語言都需要提供添加文件內(nèi)容的方法。node.js提供了fs.appendFile()方法。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 添加文件內(nèi)容  
fs.appendFile('./test.txt', '\r\nHello Vincent', (err)=>{  
    if(err){  
        console.log(err)  
        return;  
    }  
    console.log('appendFile 成功')  
})

這時(shí),如果我們打開test.txt文件,就會(huì)看到創(chuàng)建時(shí)寫入的"Hello, node.js"以及這次我們添加的"Hello Vincent"。其中的"\r\n"是回車和換行。

Hello, node.js

Hello Vincent

讀取文件內(nèi)容

方法:fs.readFile(), 是一個(gè)異步方法。

示例如下。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 讀取文件內(nèi)容  
fs.readFile('./test.txt', (err, data)=>{  
    if(err){  
        consolog.log(err)  
        return  
    }  
    console.log(data.toString())  
})

讀取目錄

調(diào)用方法:fs.readdir(),讀取后輸出該目錄下的子目錄和文件。

示例代碼

//1. 引入fs模塊  
const fs = require('fs');  
//2. 讀取  
fs.readdir('.', (err, data)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log(data)  
})

輸出如下

D:\Projects\nodejs\NodeDemo>node app.js  
[ 'app.js', 'testDir', 'package.json', 'test.txt' ]

重命名

調(diào)用方法fs.rename()。這個(gè)方法要注意的是,一方面是重命名,另一方面如果如果目標(biāo)文件不在同一個(gè)目錄,那么這個(gè)方法其實(shí)是移動(dòng)文件到目標(biāo)目錄。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 重命名,移動(dòng)文件(本例為移動(dòng)文件)  
fs.rename('./test.txt', './testDir/test.txt', (err) => {  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('移動(dòng)文件成功')  
})

上述示例把當(dāng)前目錄下的test.txt文件移動(dòng)到了./testDir目錄下。

刪除文件

調(diào)用方法:fs.unlink()

示例代碼

//1. 引入fs模塊  
const fs = require('fs');  
//2. 刪除文件  
fs.unlink('./test.txt', (err)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('刪除文件成功')  
})

刪除目錄

調(diào)用方法: fs.rmdir().需要注意的是只有當(dāng)目錄是一個(gè)空目錄時(shí),才能被刪除,否則會(huì)報(bào)錯(cuò)。所以需要先遍歷目錄,將目錄下的文件或者子目錄刪除后,才能刪除當(dāng)前目錄。如果子目錄下還有子目錄,就需要遞歸了。通過npm也可以下載另外的文件處理模塊,可以直接刪除目錄,當(dāng)然里面已經(jīng)封裝好了刪除文件和子目錄的代碼。

下面是一個(gè)空目錄刪除的示例

//1. 引入fs模塊  
const fs = require('fs');  
//2. 刪除目錄  
fs.rmdir('./testDir', (err)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('刪除目錄成功')  
})

字節(jié)流

在進(jìn)入文件拷貝之前,我們有必要了解一下字節(jié)流。對(duì)于大文件的讀取和寫入,此時(shí)通過字節(jié)流來進(jìn)行。

  • 使用字節(jié)流讀取文件:fs.createReadStream()
  • 使用字節(jié)流寫入文件:fs.createWriteStream()

拷貝文件

首先需要使用字節(jié)流讀取源文件,然后創(chuàng)建寫入文件流,最后通過pipe()方法進(jìn)行拷貝。

const fs = require('fs')  
var readStream = fs.createReadStream('./test.MOV')  
  
var writeStream = fs.createWriteStream('./data/copied.MOV')  
readStream.pipe(writeStream)

代碼量很少,簡(jiǎn)單方便,整個(gè)文件的拷貝就成功了。

總結(jié)

node.js對(duì)于文件的處理總體來說是簡(jiǎn)單便捷的,代碼量少。異步操作貫穿真?zhèn)€fs模塊,在實(shí)際編碼工作中也是有一點(diǎn)挑戰(zhàn)的。上面也講過,實(shí)際工作中可以通過封裝fs模塊,寫自己的文件操作模塊,封裝目錄刪除等。npm管理中也有一些文件操作模塊可以借鑒。

歡迎朋友們留言交流。

node.js會(huì)不斷更新,后續(xù)包括http, url, 數(shù)據(jù)庫操作等內(nèi)容。本文參考原文-http://bjbsair.com/2020-03-22/tech-info/2819/
在講完了模塊概念后,這一篇我們看一下node.js中的文件操作。文件操作的API在fs模塊中,fs全稱為 "File System"。

絕大部分編程語言都會(huì)提供文件操作功能,node.js也不例外。下面我們主要看一下文件/目錄的判斷,文件的新增,刪除,讀取,寫入,重命名和拷貝等。

node.js 07 文件操作

node.js 文件操作

node.js有一個(gè)很大的特點(diǎn),就是異步操作。這一點(diǎn)在文件操作中也一樣。有些語言判斷文件還是目錄不會(huì)使用異步,但是node.js不一樣,使用異步,通過回調(diào)函數(shù)進(jìn)行處理。

所以學(xué)習(xí)node.js一定要有異步的概念,回調(diào)函數(shù)也是必須要理解的。后面會(huì)有關(guān)于異步處理的專門講解。

如何判斷傳入路徑為文件還是目錄

首先需要引入fs模塊,然后通過fs.stat方法中的回調(diào)函數(shù)進(jìn)行判斷對(duì)象是文件還是目錄。

看一下示例代碼,個(gè)人一直認(rèn)為寫代碼不寫注釋就是拒絕團(tuán)隊(duì)合作,拒絕知識(shí)共享。

//1. 引入fs模塊  
const fs = require('fs');  
  
//2. 調(diào)用fs.stat方法,傳入文件,通過回調(diào)函數(shù)處理data對(duì)象  
fs.stat('./package.json', (err,data)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
      
    //3. 調(diào)用 isFile()方法判斷是否為文件  
    console.log(`is file: ${data.isFile()}`)  
    //4. 調(diào)用 isDirectory()方法判斷是否為目錄  
    console.log(`is directory: ${data.isDirectory()}`)  
})

由于package.json是一個(gè)文件,所以打印輸出時(shí)isFile:true。輸出結(jié)果如下:

D:\Projects\nodejs\NodeDemo>node app.js  
  
is file: true  
  
is directory: false

創(chuàng)建目錄

同樣需要引入"fs"模塊。由于所有的文件操作都需要引入"fs"模塊,后面的示例將不再強(qiáng)調(diào)。然后調(diào)用fs.mkdir()方法進(jìn)行創(chuàng)建。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 調(diào)用mkdir()方法創(chuàng)建目錄  
fs.mkdir('./testDir', (err)=>{  
    if(err){  
        console.log(err);  
        return;  
    }  
    console.log('創(chuàng)建目錄完成')  
})

創(chuàng)建文件并寫入文件

在創(chuàng)建文件時(shí)可以通過方法fs.writeFile()直接創(chuàng)建,并寫入內(nèi)容。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 創(chuàng)建并寫入文件  
fs.writeFile('./test.txt','Hello, node.js', (err)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('創(chuàng)建寫入文件成功')  
})

上面的代碼示例創(chuàng)建了文件test.txt,并在文件中寫入了"Hello, node.js"。

添加文件內(nèi)容

如果只是在創(chuàng)建的時(shí)候?qū)懭胛募?nèi)容肯定是不夠的,任何處理文件的語言都需要提供添加文件內(nèi)容的方法。node.js提供了fs.appendFile()方法。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 添加文件內(nèi)容  
fs.appendFile('./test.txt', '\r\nHello Vincent', (err)=>{  
    if(err){  
        console.log(err)  
        return;  
    }  
    console.log('appendFile 成功')  
})

這時(shí),如果我們打開test.txt文件,就會(huì)看到創(chuàng)建時(shí)寫入的"Hello, node.js"以及這次我們添加的"Hello Vincent"。其中的"\r\n"是回車和換行。

Hello, node.js

Hello Vincent

讀取文件內(nèi)容

方法:fs.readFile(), 是一個(gè)異步方法。

示例如下。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 讀取文件內(nèi)容  
fs.readFile('./test.txt', (err, data)=>{  
    if(err){  
        consolog.log(err)  
        return  
    }  
    console.log(data.toString())  
})

讀取目錄

調(diào)用方法:fs.readdir(),讀取后輸出該目錄下的子目錄和文件。

示例代碼

//1. 引入fs模塊  
const fs = require('fs');  
//2. 讀取  
fs.readdir('.', (err, data)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log(data)  
})

輸出如下

D:\Projects\nodejs\NodeDemo>node app.js  
[ 'app.js', 'testDir', 'package.json', 'test.txt' ]

重命名

調(diào)用方法fs.rename()。這個(gè)方法要注意的是,一方面是重命名,另一方面如果如果目標(biāo)文件不在同一個(gè)目錄,那么這個(gè)方法其實(shí)是移動(dòng)文件到目標(biāo)目錄。

//1. 引入fs模塊  
const fs = require('fs');  
//2. 重命名,移動(dòng)文件(本例為移動(dòng)文件)  
fs.rename('./test.txt', './testDir/test.txt', (err) => {  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('移動(dòng)文件成功')  
})

上述示例把當(dāng)前目錄下的test.txt文件移動(dòng)到了./testDir目錄下。

刪除文件

調(diào)用方法:fs.unlink()

示例代碼

//1. 引入fs模塊  
const fs = require('fs');  
//2. 刪除文件  
fs.unlink('./test.txt', (err)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('刪除文件成功')  
})

刪除目錄

調(diào)用方法: fs.rmdir().需要注意的是只有當(dāng)目錄是一個(gè)空目錄時(shí),才能被刪除,否則會(huì)報(bào)錯(cuò)。所以需要先遍歷目錄,將目錄下的文件或者子目錄刪除后,才能刪除當(dāng)前目錄。如果子目錄下還有子目錄,就需要遞歸了。通過npm也可以下載另外的文件處理模塊,可以直接刪除目錄,當(dāng)然里面已經(jīng)封裝好了刪除文件和子目錄的代碼。

下面是一個(gè)空目錄刪除的示例

//1. 引入fs模塊  
const fs = require('fs');  
//2. 刪除目錄  
fs.rmdir('./testDir', (err)=>{  
    if(err){  
        console.log(err)  
        return  
    }  
    console.log('刪除目錄成功')  
})

字節(jié)流

在進(jìn)入文件拷貝之前,我們有必要了解一下字節(jié)流。對(duì)于大文件的讀取和寫入,此時(shí)通過字節(jié)流來進(jìn)行。

  • 使用字節(jié)流讀取文件:fs.createReadStream()
  • 使用字節(jié)流寫入文件:fs.createWriteStream()

拷貝文件

首先需要使用字節(jié)流讀取源文件,然后創(chuàng)建寫入文件流,最后通過pipe()方法進(jìn)行拷貝。

const fs = require('fs')  
var readStream = fs.createReadStream('./test.MOV')  
  
var writeStream = fs.createWriteStream('./data/copied.MOV')  
readStream.pipe(writeStream)

代碼量很少,簡(jiǎn)單方便,整個(gè)文件的拷貝就成功了。

總結(jié)

node.js對(duì)于文件的處理總體來說是簡(jiǎn)單便捷的,代碼量少。異步操作貫穿真?zhèn)€fs模塊,在實(shí)際編碼工作中也是有一點(diǎn)挑戰(zhàn)的。上面也講過,實(shí)際工作中可以通過封裝fs模塊,寫自己的文件操作模塊,封裝目錄刪除等。npm管理中也有一些文件操作模塊可以借鑒。

歡迎朋友們留言交流。

node.js會(huì)不斷更新,后續(xù)包括http, url, 數(shù)據(jù)庫操作等內(nèi)容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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