Node.js內(nèi)置的fs模塊就是文件系統(tǒng)模塊,負責讀寫文件。
和所有其它JavaScript模塊不同的是踩蔚,fs模塊同時提供了異步和同步的方法。
回顧一下什么是異步方法桩盲。
- 因為JavaScript的單線程模型,執(zhí)行IO操作時席吴,JavaScript代碼無需等待赌结,而是傳入回調(diào)函數(shù)后捞蛋,繼續(xù)執(zhí)行后續(xù)JavaScript代碼。
// 獲取遠程 json 數(shù)據(jù)
$.getJSON('http://example.com/ajax', function (data) { console.log('IO結(jié)果返回后執(zhí)行...');});
console.log('不等待IO結(jié)果直接執(zhí)行后續(xù)代碼...');
- 而同步的IO操作則需要等待函數(shù)返回:
// 根據(jù)網(wǎng)絡(luò)耗時柬姚,函數(shù)將執(zhí)行幾十毫秒~幾秒不等:
// 獲取遠程 json 數(shù)據(jù)
var data = getJSONSync('http://example.com/ajax');
同步操作的好處是代碼簡單拟杉,缺點是程序?qū)⒌却齀O操作,在等待時間內(nèi)量承,無法響應(yīng)其它任何事件搬设。而異步讀取不用等待IO操作,但代碼較麻煩撕捍。
異步讀文件
異步讀取文件使用的是 fs 模塊中的 readFile 方法拿穴。
手冊地址
https://nodejs.org/api/fs.html#fs_fs_readfile_file_options_callback
最起碼 要傳入兩個參數(shù)
- 文件路徑
- 回調(diào)方法
先創(chuàng)建一個 sample.txt 文本,內(nèi)容如下
黃河遠上白云間忧风,一片孤城萬仞山默色。
羌笛何須怨楊柳,春風不度玉門關(guān)狮腿。
創(chuàng)建讀取腳本 fs.js
// 引入文件系統(tǒng)管理模塊
const FS = require('fs');
// 讀取文件
FS.readFile('sample.txt', 'utf-8', function (err, data) {
console.log("\n ====== 讀取文件內(nèi)容 \n");
// 如果報錯的話就打印 錯誤
if (err) {
console.log(err);
// 如果沒有錯誤的話 就輸出內(nèi)容
} else {
console.log(data.toString());
}
console.log("\n");
});
// 當正常讀取時腿宰,err參數(shù)為null,data參數(shù)為讀取到的String缘厢。
// 傳入的回調(diào)函數(shù)接收兩個參數(shù)吃度,err 和 data
// 當讀取發(fā)生錯誤時,err參數(shù)代表一個錯誤對象贴硫,data為undefined椿每。
// 這也是Node.js標準的回調(diào)函數(shù):第一個參數(shù)代表錯誤信息,第二個參數(shù)代表結(jié)果夜畴。后面我們還會經(jīng)常編寫這種回調(diào)函數(shù)拖刃。
同步讀文件
除了標準的異步讀取模式外,fs也提供相應(yīng)的同步讀取函數(shù)贪绘。同步讀取的函數(shù)和異步函數(shù)相比兑牡,多了一個Sync后綴,并且不接收回調(diào)函數(shù)税灌,函數(shù)直接返回結(jié)果均函。
案例
var fs = require('fs');var data = fs.readFileSync('sample.txt', 'utf-8');
console.log(data);
異步寫文件
將數(shù)據(jù)寫入文件是通過fs.writeFile()實現(xiàn)的
文檔地址
https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
var fs = require('fs');
var data = 'Hello, Node.js';
fs.writeFile('output.txt', data, function(err) {
if (err) {
console.log(err);
} else {
console.log('ok.');
}
});
- writeFile()的參數(shù)依次為文件名、數(shù)據(jù)和回調(diào)函數(shù)菱涤。
- 如果傳入的數(shù)據(jù)是String苞也,默認按UTF-8編碼寫入文本文件,如果傳入的參數(shù)是Buffer粘秆,則寫入的是二進制文件如迟。
- 回調(diào)函數(shù)由于只關(guān)心成功與否,因此只需要一個err參數(shù)。
同步寫文件
同步寫入文件是通過fs.writeFileSync()實現(xiàn)的
文檔地址
https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options
var fs = require('fs');
var data = 'Hello, Node.js';
fs.writeFileSync('output.txt', data);
獲取文件信息 stat
如果我們要獲取文件大小殷勘,創(chuàng)建時間等信息此再,可以使用fs.stat(),它返回一個Stat對象玲销,能告訴我們文件或目錄的詳細信息:
var fs = require('fs');
fs.stat('sample.txt', function(err, stat) {
if (err) {
console.log(err);
} else {
// 是否是文件:
console.log('isFile: ' + stat.isFile());
// 是否是目錄:
console.log('isDirectory: ' + stat.isDirectory());
// 如果是文件 答應(yīng)文件信息
if (stat.isFile()) {
// 文件大小:
console.log('size: ' + stat.size);
// 創(chuàng)建時間, Date對象:
console.log('birth time: ' + stat.birthtime);
// 修改時間, Date對象:
console.log('modified time: ' + stat.mtime);
}
}
});
stat 也有一個同步的函數(shù) statSync
var fs = require('fs');
var data = fs.statSync('sample.txt');
console.log(data);
異步還是同步
在fs 模塊中输拇,提供同步方法是為了方便使用。那我們到底是應(yīng)該用異步方法還是同步方法呢贤斜?
由于Node環(huán)境執(zhí)行的JavaScript代碼是服務(wù)器端代碼策吠,所以,絕大部分需要在服務(wù)器運行期反復執(zhí)行業(yè)務(wù)邏輯的代碼瘩绒,必須使用異步代碼猴抹,否則,同步代碼在執(zhí)行時期草讶,服務(wù)器將停止響應(yīng)洽糟,因為JavaScript只有一個執(zhí)行線程。
服務(wù)器啟動時如果需要讀取配置文件堕战,或者結(jié)束時需要寫入到狀態(tài)文件時坤溃,可以使用同步代碼,因為這些代碼只在啟動和結(jié)束時執(zhí)行一次嘱丢,不影響服務(wù)器正常運行時的異步執(zhí)行薪介。