Node.js內(nèi)置的fs模塊就是文件系統(tǒng)模塊,負責侠姑。
和所有其它JavaScript模塊不同的是创橄,fs模塊同時提供了和的方法。
回顧一下什么是異步方法莽红。因為JavaScript的單線程模型妥畏,執(zhí)行IO操作時,JavaScript代碼無需等待安吁,而是傳入回調(diào)函數(shù)后醉蚁,繼續(xù)執(zhí)行后續(xù)JavaScript代碼。比如jQuery提供的getJSON()操作:例子(本地請求有跨域問題柳畔,建議自己寫一個接口)
$.getJSON('https://example.com/ajax',function(data){
console.log('IO結果返回後執(zhí)行')
})
console.log('不等待IO結果直接執(zhí)行後續(xù)代碼')
結果:
console.log('不等待IO結果直接執(zhí)行後續(xù)代碼')
console.log('IO結果返回後執(zhí)行')
而同步的IO操作則需要等待函數(shù)返回:
同步操作的好處是代碼簡單馍管,缺點是程序?qū)⒌却齀O操作,在等待時間內(nèi)薪韩,無法響應其它任何事件确沸。而異步讀取不用等待IO操作,但代碼較麻煩俘陷。
按照JavaScript的標準罗捎,異步讀取一個文本文件的代碼如下:
(index6.js)
'use strict'
var fs = require('fs');
fs.readFile('./text.text','utf-8',function(err,data){
if(err){
console.log(err);
}else{
console.log(data)
}
})
(text.text)
666
console.log(888)
(index8.js)
'use strict'
var fs = require('fs');
fs.readFile('./image/index5.png',function(err,data){ (圖片自找,屬於二進制,返回buffer對象)
if(err){
console.log(err)
}else{
console.log(data);
console.log(data.length + 'bytes')
}
// var text = data.toString('utf-8'); 把一個Buffer對象轉(zhuǎn)換成String
// console.log(text);
// var buf = Buffer.from(text, 'utf-8'); 把一個String轉(zhuǎn)換成Buffer:
// console.log(buf);
})
除了標準的異步讀取模式外拉盾,fs也提供相應的同步讀取函數(shù)桨菜。同步讀取的函數(shù)和異步函數(shù)相比,多了一個Sync后綴,并且倒得,函數(shù)直接返回結果泻红。
用fs模塊同步讀取一個文本文件的代碼如下:
'use strict'
var fs = require('fs');
var data = fs.readFileSync('text.text','utf-8');
console.log(data)
如果同步讀取文件發(fā)生錯誤,則需要用try...catch捕獲該錯誤:
'use strict'
var fs = require('fs')
try{
var data = fs.readFileSync('text.text','utf-8')
console.log(data)
}catch(err){
console.log(err+"666")
}
'use strict'
var fs = require('fs')
try{
var data = fs.readFileSync('text.tex','utf-8') //<-.text.text
console.log(data)
}catch(err){
console.log(err+"666")
}
(index11.js)
'use strict'
var fs = require('fs')
var data = 'Hello, Node.js'
var read = fs.readFileSync('text.text','utf-8')
console.log(read)
fs.writeFile('text.text',data,function(err){ //文件霞掺、數(shù)據(jù)谊路、回調(diào)
if(err){
console.log(err)
}else{
read = fs.readFileSync('text.text','utf-8')
console.log('ok')
console.log(read)
}
})
writeFileSync()和readFileSync()一樣;
如果我們要獲取文件大小菩彬,創(chuàng)建時間等信息缠劝,可以使用fs.stat(),它返回一個Stat對象骗灶,能告訴我們文件或目錄的詳細信息:
'use strit'
var fs = require('fs')
var date = fs.stat('text.text',function(err,stat){
if(err){
console.log(err)
}else{
//是否文件
console.log('isFile:' + stat.isFile())
//是否目錄
console.log('isDirectory:' + stat.isDirectory())
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(),請試著改寫上述異步代碼為同步代碼耙旦。
異步還是同步
在fs模塊中脱羡,提供同步方法是為了方便使用。那我們到底是應該用異步方法還是同步方法呢母廷?
由于Node環(huán)境執(zhí)行的JavaScript代碼是服務器端代碼轻黑,所以糊肤,絕大部分需要在服務器運行期反復執(zhí)行業(yè)務邏輯的代碼琴昆,必須使用異步代碼,否則馆揉,同步代碼在執(zhí)行時期业舍,服務器將停止響應,因為JavaScript只有一個執(zhí)行線程升酣。
服務器啟動時如果需要讀取配置文件舷暮,或者結束時需要寫入到狀態(tài)文件時,可以使用同步代碼噩茄,因為這些代碼只在啟動和結束時執(zhí)行一次下面,不影響服務器正常運行時的異步執(zhí)行。