NodeJS 學習來到 file systems 操作,在文檔操作上有分為同步跟異步的處理,接下來分階段介紹操作函數
//異步寫入文件
fs.writeFile(file, data[, options], callback)
參數使用說明如下:
// 如果文件不存在則直接創建,options 第三個參數為一個可選參數,這邊不寫
// 直接寫回調函數 callback
//導入fs 模塊
const fs = require('fs');
// 導入fs 模塊
const fs = require('fs');
// 寫入文件
fs.writeFile('./123.txt', 'test_test', err => {
if(err){
console.log('寫入失敗');
return;
}
console.log('寫入成功');
})
而在異步處理下會先執行主要的JS線程,而到檔案做寫入時是走IO線程,故為異步操作, 而主線程不等待回調結果,直接往下執行,我們試著在最後增加一個 console.log(1+1);
驗證流程結果
// 如果文件不存在則直接創建,options 第三個參數為一個可選參數,這邊不寫
// 直接寫回調函數 callback
//導入fs 模塊
const fs = require('fs');
// 導入fs 模塊
const fs = require('fs');
// 寫入文件
fs.writeFile('./123.txt', 'test_test', err => {
if(err){
console.log('寫入失敗');
return;
}
console.log('寫入成功');
})
console.log(1+1);
而整個執行,會是如下圖所示,故異步執行效率會較高
//同步寫入文件,差別無回調函數
fs.writeFileSync(filename, data[, options])
// 同步寫入文件
fs.writeFileSync('./456.text', 'testSync')
參數使用說明如下:
同步寫入的操作,主要是由JS主線程執行然後送到IO線程處理,等待處理完畢後再寫回,才由主線程繼續執行,處理方式無異步效率高。
接下來說明當文件寫入一半,需要持續寫入的時候的應用,這時候可以使用file systems
下的appendFile
去讀取文件並將資料寫入
//异步追加文件内容
fs.appendFile(filename, data[, options], callback)
//異步追加寫入
fs.appendFile('./123.txt', ',這是要追加的內容', err => {
if(err){
console.log('寫入失敗');
return;
}
console.log('追加寫入成功');
});
第一個參數選擇要寫入的檔案名稱,第二個參數帶入要追加的文檔,在包含一個回調函數。
如果寫入想要要換行,在JS裡面是使用\r\n
//同步追加文件内容
fs.appendFile. fs.appendFileSync(filename, data[, options])
//同步追加寫入
fs.appendFileSync('./456.text', 'testSync追加的內容')
//同步追加寫入
fs.appendFileSync('./456.text', '\r\ntestSync追加的內容')
而如果使用上面原本的fs.writeFile
想作為追加寫入的行為,可以在option參數加上 {flag: 'a'},即可實現追加寫入
//異步寫入文件仿照追加寫入
fs.writeFile('./123.txt', 'yoyo', {flag: 'a'}, err => {
if(err){
console.log('寫入失敗');
return;
}
console.log('寫入成功');
});
而這裡的flag: 'a'
主要是append
的意思,即是打開文件進行寫入的操作,這表示當文件已存在,則新的數據將會追加到文件的末尾,而不是覆蓋原有內容。
而option其他參數可以參考以下
這邊講解FS流式寫入使用createWriteStream
方法。
fs.createWriteStream(path[, options])
createWriteStream 與 writeFile 差異在於writeFile一次性處理完畢後就斷開連接通道,而createWriteStream會持續連接通道直到關閉,而適合持續寫入的場景,writeFile則適合寫入較少的場景。
// 導入fs 模塊
const fs = require('fs');
// 1.創建寫入流
const ws = fs.createWriteStream('./789.txt');
// 2. write
ws.write('123');
ws.write('456');
ws.write('789');
ws.write('101112');
// 3. 關閉通道
ws.close(); //這個步驟為可選,因為正常在寫入完成後,資源將會被釋放出來而斷開
在 file systems文件讀取也分為異步fs.readFile()
及同步fs.readFileSync()
//異步讀取文件
fs.readFile(filename[, options], callback)
//同步讀取文件
fs.readFileSync(filename[, options])
而fs.readFile 的callback function 有兩個參數
// 導入fs 模塊
const fs = require('fs');
// 異步讀取
fs.readFile('./123.txt', (err, data) => {
if(err){ console.log('寫入失敗');
return;
}
console.log(data); }); // err 作為錯誤訊息的回調,data 為接收讀取資料的結果
這邊可以看到讀取到的內容是一個 buffer ,而需要知道實際內容可以透過toString()方法將buffer轉成字串。
// 導入fs 模塊
const fs = require('fs'); // 異步讀取
fs.readFile('./123.txt', (err, data) => {
if(err){ console.log('寫入失敗');
return;
}
console.log(data.toString());
而如果是使用同步讀取的方式,只要帶入文件路徑即可
// 同步讀取
let data = fs.readFileSync('./123.txt');
console.log(data.toString());
流式讀取主要是切割多個chunk 一次讀取一個chunk執行,在實際應用上讀取大型文件時可以提高讀取效率。
fs.createReadStream(path[, options])
在讀取文件後回調函數的執行,是當讀取一塊數據就會執行一次回調,這邊創建讀取一個mp4的檔案,綁定一個data事件並console.log(chunk)
看看結果。
// 導入fs 模塊
const fs = require('fs');
// 創建讀取流對象
const rs = fs.createReadStream('./video.mp4');
// 綁定data事件
rs.on('data', chunk => { console.log(chunk) })
而我們可以透過使用lenght
來知道獲取buffer的長度,可以打印出來後看到每一次切割為65536 => 64KB => 表示一次讀取一個64KB的 chunk
// 導入fs 模塊
const fs = require('fs');
// 創建讀取流對象
const rs = fs.createReadStream('./video.mp4');
// 綁定data事件
rs.on('data', chunk => { console.log(chunk.length)
而使用上在讀取流中執行,通常會觸發一個end事件,而這個事件是可選的,可加可不加
// 導入fs 模塊
const fs = require('fs');
// 創建讀取流對象
const rs = fs.createReadStream('./video.mp4');
// 綁定data事件
rs.on('data', chunk => {
console.log(chunk.length)
})
// end
rs.on('end', () => {
console.log('讀取完成');
})
小結:以上就是關於 file systems 對於檔案的寫入操作,下一篇就要說明關於file systems的文件讀取方法應用~