Node.js的文件系統(tǒng)的Api
//公共引用
var fs = require('fs'),
path = require('path');
1、讀取文件readFile函數(shù)
//readFile(filename,[options],callback);
/**
* filename, 必選參數(shù)丑婿,文件名
* [options],可選參數(shù)性雄,可指定flag(文件操作選項(xiàng)没卸,如r+ 讀寫(xiě);w+ 讀寫(xiě)秒旋,文件不存在則創(chuàng)建)及encoding屬性
* callback 讀取文件后的回調(diào)函數(shù)约计,參數(shù)默認(rèn)第一個(gè)err,第二個(gè)data 數(shù)據(jù)
*/
fs.readFile(__dirname + '/test.txt', {flag: 'r+', encoding: 'utf8'}, function (err, data) {
if(err) {
console.error(err);
return;
}
console.log(data);
});
2、寫(xiě)文件
// fs.writeFile(filename,data,[options],callback);
var w_data = '這是一段通過(guò)fs.writeFile函數(shù)寫(xiě)入的內(nèi)容迁筛;\r\n';
var w_data = new Buffer(w_data);
/**
* filename, 必選參數(shù)煤蚌,文件名
* data, 寫(xiě)入的數(shù)據(jù),可以字符或一個(gè)Buffer對(duì)象
* [options],flag,mode(權(quán)限),encoding
* callback 讀取文件后的回調(diào)函數(shù)细卧,參數(shù)默認(rèn)第一個(gè)err,第二個(gè)data 數(shù)據(jù)
*/
fs.writeFile(__dirname + '/test.txt', w_data, {flag: 'a'}, function (err) {
if(err) {
console.error(err);
} else {
console.log('寫(xiě)入成功');
}
});
3铺然、以追加方式寫(xiě)文件
// fs.appendFile(filename,data,[options],callback);
fs.appendFile(__dirname + '/test.txt', '使用fs.appendFile追加文件內(nèi)容', function () {
console.log('追加內(nèi)容完成');
});
4、打開(kāi)文件
// fs.open(filename, flags, [mode], callback);
/**
* filename, 必選參數(shù)酒甸,文件名
* flags, 操作標(biāo)識(shí)魄健,如"r",讀方式打開(kāi)
* [mode],權(quán)限,如777插勤,表示任何用戶讀寫(xiě)可執(zhí)行
* callback 打開(kāi)文件后回調(diào)函數(shù)沽瘦,參數(shù)默認(rèn)第一個(gè)err,第二個(gè)fd為一個(gè)整數(shù),表示打開(kāi)文件返回的文件描述符农尖,window中又稱文件句柄
*/
fs.open(__dirname + '/test.txt', 'r', '0666', function (err, fd) {
console.log(fd);
});
5析恋、讀文件,讀取打開(kāi)的文件內(nèi)容到緩沖區(qū)中盛卡;
//fs.read(fd, buffer, offset, length, position, callback);
/**
* fd, 使用fs.open打開(kāi)成功后返回的文件描述符
* buffer, 一個(gè)Buffer對(duì)象助隧,v8引擎分配的一段內(nèi)存
* offset, 整數(shù),向緩存區(qū)中寫(xiě)入時(shí)的初始位置滑沧,以字節(jié)為單位
* length, 整數(shù)并村,讀取文件的長(zhǎng)度
* position, 整數(shù),讀取文件初始位置滓技;文件大小以字節(jié)為單位
* callback(err, bytesRead, buffer), 讀取執(zhí)行完成后回調(diào)函數(shù)哩牍,bytesRead實(shí)際讀取字節(jié)數(shù),被讀取的緩存區(qū)對(duì)象
*/
fs.open(__dirname + '/test.txt', 'r', function (err, fd) {
if(err) {
console.error(err);
return;
} else {
var buffer = new Buffer(255);
console.log(buffer.length);
//每一個(gè)漢字utf8編碼是3個(gè)字節(jié)令漂,英文是1個(gè)字節(jié)
fs.read(fd, buffer, 0, 9, 3, function (err, bytesRead, buffer) {
if(err) {
throw err;
} else {
console.log(bytesRead);
console.log(buffer.slice(0, bytesRead).toString());
//讀取完后膝昆,再使用fd讀取時(shí),基點(diǎn)是基于上次讀取位置計(jì)算叠必;
fs.read(fd, buffer, 0, 9, null, function (err, bytesRead, buffer) {
console.log(bytesRead);
console.log(buffer.slice(0, bytesRead).toString());
});
}
});
}
});
6荚孵、寫(xiě)文件,將緩沖區(qū)內(nèi)數(shù)據(jù)寫(xiě)入使用fs.open打開(kāi)的文件
//fs.write(fd, buffer, offset, length, position, callback);
/**
* fd, 使用fs.open打開(kāi)成功后返回的文件描述符
* buffer, 一個(gè)Buffer對(duì)象纬朝,v8引擎分配的一段內(nèi)存
* offset, 整數(shù)收叶,從緩存區(qū)中讀取時(shí)的初始位置,以字節(jié)為單位
* length, 整數(shù)玄组,從緩存區(qū)中讀取數(shù)據(jù)的字節(jié)數(shù)
* position, 整數(shù)滔驾,寫(xiě)入文件初始位置谒麦;
* callback(err, written, buffer), 寫(xiě)入操作執(zhí)行完成后回調(diào)函數(shù),written實(shí)際寫(xiě)入字節(jié)數(shù)哆致,buffer被讀取的緩存區(qū)對(duì)象
*/
fs.open(__dirname + '/test.txt', 'a', function (err, fd) {
if(err) {
console.error(err);
return;
} else {
var buffer = new Buffer('寫(xiě)入文件數(shù)據(jù)內(nèi)容');
//寫(xiě)入'入文件'三個(gè)字
fs.write(fd, buffer, 3, 9, 12, function (err, written, buffer) {
if(err) {
console.log('寫(xiě)入文件失敗');
console.error(err);
return;
} else {
console.log(buffer.toString());
//寫(xiě)入'數(shù)據(jù)內(nèi)'三個(gè)字
fs.write(fd, buffer, 12, 9, null, function (err, written, buffer) {
console.log(buffer.toString());
})
}
});
}
});
7绕德、刷新緩存區(qū);
// 使用fs.write寫(xiě)入文件時(shí),操作系統(tǒng)是將數(shù)據(jù)讀到內(nèi)存摊阀,再把數(shù)據(jù)寫(xiě)入到文件中耻蛇,當(dāng)數(shù)據(jù)讀完時(shí)并不代表數(shù)據(jù)已經(jīng)寫(xiě)完,因?yàn)橛幸徊糠诌€可能在內(nèi)在緩沖區(qū)內(nèi)胞此。
// 因此可以使用fs.fsync方法將內(nèi)存中數(shù)據(jù)寫(xiě)入文件臣咖;--刷新內(nèi)存緩沖區(qū);
//fs.fsync(fd, [callback])
/**
* fd, 使用fs.open打開(kāi)成功后返回的文件描述符
* [callback(err, written, buffer)], 寫(xiě)入操作執(zhí)行完成后回調(diào)函數(shù)漱牵,written實(shí)際寫(xiě)入字節(jié)數(shù)夺蛇,buffer被讀取的緩存區(qū)對(duì)象
*/
fs.open(__dirname + '/test.txt', 'a', function (err, fd) {
if(err)
throw err;
var buffer = new Buffer('我愛(ài)nodejs編程');
fs.write(fd, buffer, 0, 9, 0, function (err, written, buffer) {
console.log(written.toString());
fs.write(fd, buffer, 9, buffer.length - 9, null, function (err, written) {
console.log(written.toString());
fs.fsync(fd);
fs.close(fd);
})
});
});
8、創(chuàng)建目錄;
//使用fs.mkdir創(chuàng)建目錄
//fs.mkdir(path, [mode], callback);
/**
* path, 被創(chuàng)建目錄的完整路徑及目錄名酣胀;
* [mode], 目錄權(quán)限刁赦,默認(rèn)0777
* [callback(err)], 創(chuàng)建完目錄回調(diào)函數(shù),err錯(cuò)誤對(duì)象
*/
fs.mkdir(__dirname + '/fsDir', function (err) {
if(err)
throw err;
console.log('創(chuàng)建目錄成功')
});
9、讀取目錄;
//使用fs.readdir讀取目錄闻镶,重點(diǎn)其回調(diào)函數(shù)中files對(duì)象
//fs.readdir(path, callback);
/**
* path, 要讀取目錄的完整路徑及目錄名甚脉;
* [callback(err, files)], 讀完目錄回調(diào)函數(shù);err錯(cuò)誤對(duì)象铆农,files數(shù)組牺氨,存放讀取到的目錄中的所有文件名
*/
fs.readdir(__dirname + '/fsDir/', function (err, files) {
if(err) {
console.error(err);
return;
} else {
files.forEach(function (file) {
var filePath = path.normalize(__dirname + '/fsDir/' + file);
fs.stat(filePath, function (err, stat) {
if(stat.isFile()) {
console.log(filePath + ' is: ' + 'file');
}
if(stat.isDirectory()) {
console.log(filePath + ' is: ' + 'dir');
}
});
});
for (var i = 0; i < files.length; i++) {
//使用閉包無(wú)法保證讀取文件的順序與數(shù)組中保存的致
(function () {
var filePath = path.normalize(__dirname + '/fsDir/' + files[i]);
fs.stat(filePath, function (err, stat) {
if(stat.isFile()) {
console.log(filePath + ' is: ' + 'file');
}
if(stat.isDirectory()) {
console.log(filePath + ' is: ' + 'dir');
}
});
})();
}
}
});
10、查看文件與目錄的信息;
//fs.stat(path, callback);
//fs.lstat(path, callback); //查看符號(hào)鏈接文件
/**
* path, 要查看目錄/文件的完整路徑及名墩剖;
* [callback(err, stats)], 操作完成回調(diào)函數(shù)猴凹;err錯(cuò)誤對(duì)象,stat fs.Stat一個(gè)對(duì)象實(shí)例涛碑,提供如:isFile, isDirectory,isBlockDevice等方法及size,ctime,mtime等屬性
*/
//實(shí)例精堕,查看fs.readdir
11、查看文件與目錄的是否存在
//fs.exists(path, callback);
/**
* path, 要查看目錄/文件的完整路徑及名蒲障;
* [callback(exists)], 操作完成回調(diào)函數(shù);exists true存在瘫证,false表示不存在
*/
fs.exists(__dirname + '/te', function (exists) {
var retTxt = exists ? retTxt = '文件存在' : '文件不存在';
console.log(retTxt);
});
12揉阎、修改文件訪問(wèn)時(shí)間與修改時(shí)間
//fs.utimes(path, atime, mtime, callback);
/**
* path, 要查看目錄/文件的完整路徑及名;
* atime, 新的訪問(wèn)時(shí)間
* ctime, 新的修改時(shí)間
* [callback(err)], 操作完成回調(diào)函數(shù)背捌;err操作失敗對(duì)象
*/
fs.utimes(__dirname + '/test.txt', new Date(), new Date(), function (err) {
if(err) {
console.error(err);
return;
}
fs.stat(__dirname + '/test.txt', function (err, stat) {
console.log('訪問(wèn)時(shí)間: ' + stat.atime.toString() + '; \n修改時(shí)間:' + stat.mtime);
console.log(stat.mode);
})
});
13毙籽、修改文件或目錄的操作權(quán)限
//fs.utimes(path, mode, callback);
/**
* path, 要查看目錄/文件的完整路徑及名;
* mode, 指定權(quán)限毡庆,如:0666 8進(jìn)制坑赡,權(quán)限:所有用戶可讀烙如、寫(xiě),
* [callback(err)], 操作完成回調(diào)函數(shù)毅否;err操作失敗對(duì)象
*/
fs.chmod(__dirname + '/fsDir', 0666, function (err) {
if(err) {
console.error(err);
return;
}
console.log('修改權(quán)限成功')
});
14亚铁、移動(dòng)/重命名文件或目錄
//fs.rename(oldPath, newPath, callback);
/**
* oldPath, 原目錄/文件的完整路徑及名;
* newPath, 新目錄/文件的完整路徑及名螟加;如果新路徑與原路徑相同徘溢,而只文件名不同,則是重命名
* [callback(err)], 操作完成回調(diào)函數(shù)捆探;err操作失敗對(duì)象
*/
fs.rename(__dirname + '/test', __dirname + '/fsDir', function (err) {
if(err) {
console.error(err);
return;
}
console.log('重命名成功')
});
15然爆、刪除空目錄
//fs.rmdir(path, callback);
/**
* path, 目錄的完整路徑及目錄名座菠;
* [callback(err)], 操作完成回調(diào)函數(shù)曼验;err操作失敗對(duì)象
*/
fs.rmdir(__dirname + '/test', function (err) {
fs.mkdir(__dirname + '/test', 0666, function (err) {
console.log('創(chuàng)建test目錄');
});
if(err) {
console.log('刪除空目錄失敗征堪,可能原因:1黔寇、目錄不存在炕倘,2罕邀、目錄不為空')
console.error(err);
return;
}
console.log('刪除空目錄成功!');
});
16辆童、監(jiān)視文件
//對(duì)文件進(jìn)行監(jiān)視抒痒,并且在監(jiān)視到文件被修改時(shí)執(zhí)行處理
//fs.watchFile(filename, [options], listener);
/**
* filename, 完整路徑及文件名恰起;
* [options], persistent true表示持續(xù)監(jiān)視修械,不退出程序;interval 單位毫秒检盼,表示每隔多少毫秒監(jiān)視一次文件
* listener, 文件發(fā)生變化時(shí)回調(diào)肯污,有兩個(gè)參數(shù):curr為一個(gè)fs.Stat對(duì)象,被修改后文件吨枉,prev,一個(gè)fs.Stat對(duì)象蹦渣,表示修改前對(duì)象
*/
fs.watchFile(__dirname + '/test.txt', {interval: 20}, function (curr, prev) {
if(Date.parse(prev.ctime) == 0) {
console.log('文件被創(chuàng)建!');
} else if(Date.parse(curr.ctime) == 0) {
console.log('文件被刪除!')
} else if(Date.parse(curr.mtime) != Date.parse(prev.mtime)) {
console.log('文件有修改');
}
});
fs.watchFile(__dirname + '/test.txt', function (curr, prev) {
console.log('這是第二個(gè)watch,監(jiān)視到文件有修改');
});
17、取消監(jiān)視文件
//取消對(duì)文件進(jìn)行監(jiān)視
//fs.unwatchFile(filename, [listener]);
/**
* filename, 完整路徑及文件名貌亭;
* [listener], 要取消的監(jiān)聽(tīng)器事件柬唯,如果不指定,則取消所有監(jiān)聽(tīng)處理事件
*/
var listener = function (curr, prev) {
console.log('我是監(jiān)視函數(shù)')
}
fs.unwatchFile(__dirname + '/test.txt', listener);
18圃庭、監(jiān)視文件或目錄
// 對(duì)文件或目錄進(jìn)行監(jiān)視锄奢,并且在監(jiān)視到修改時(shí)執(zhí)行處理;
// fs.watch返回一個(gè)fs.FSWatcher對(duì)象拘央,擁有一個(gè)close方法,用于停止watch操作书在;
// 當(dāng)fs.watch有文件變化時(shí)灰伟,會(huì)觸發(fā)fs.FSWatcher對(duì)象的change(err, filename)事件,err錯(cuò)誤對(duì)象儒旬,filename發(fā)生變化的文件名
// fs.watch(filename, [options], [listener]);
/**
* filename, 完整路徑及文件名或目錄名栏账;
* [listener(event, filename], 監(jiān)聽(tīng)器事件帖族,有兩個(gè)參數(shù):event 為rename表示指定的文件或目錄中有重命名、刪除或移動(dòng)操作或change表示有修改挡爵,filename表示發(fā)生變化的文件路徑
*/
var fsWatcher = fs.watch(__dirname + '/test', function (event, filename) {
//console.log(event)
});
//console.log(fsWatcher instanceof FSWatcher);
fsWatcher.on('change', function (event, filename) {
console.log(filename + ' 發(fā)生變化')
});
//30秒后關(guān)閉監(jiān)視
setTimeout(function () {
console.log('關(guān)閉')
fsWatcher.close(function (err) {
if(err) {
console.error(err)
}
console.log('關(guān)閉watch')
});
}, 30000);
19竖般、文件流
/*
* 流,在應(yīng)用程序中表示一組有序的了讨、有起點(diǎn)有終點(diǎn)的字節(jié)數(shù)據(jù)的傳輸手段捻激;
* Node.js中實(shí)現(xiàn)了stream.Readable/stream.Writeable接口的對(duì)象進(jìn)行流數(shù)據(jù)讀寫(xiě);以上接口都繼承自EventEmitter類前计,因此在讀/寫(xiě)流不同狀態(tài)時(shí)胞谭,觸發(fā)不同事件;
* 關(guān)于流讀饶需尽:Node.js不斷將文件一小塊內(nèi)容讀入緩沖區(qū)丈屹,再?gòu)木彌_區(qū)中讀取內(nèi)容;
* 關(guān)于流寫(xiě)入:Node.js不斷將流數(shù)據(jù)寫(xiě)入內(nèi)在緩沖區(qū)伶棒,待緩沖區(qū)滿后再將緩沖區(qū)寫(xiě)入到文件中旺垒;重復(fù)上面操作直到要寫(xiě)入內(nèi)容寫(xiě)寫(xiě)完;
* readFile肤无、read先蒋、writeFile、write都是將整個(gè)文件放入內(nèi)存而再操作宛渐,而則是文件一部分?jǐn)?shù)據(jù)一部分?jǐn)?shù)據(jù)操作竞漾;
*
* -----------------------流讀取-------------------------------------
* 讀取數(shù)據(jù)對(duì)象:
* fs.ReadStream 讀取文件
* http.IncomingMessage 客戶端請(qǐng)求或服務(wù)器端響應(yīng)
* net.Socket Socket端口對(duì)象
* child.stdout 子進(jìn)程標(biāo)準(zhǔn)輸出
* child.stdin 子進(jìn)程標(biāo)準(zhǔn)入
* process.stdin 用于創(chuàng)建進(jìn)程標(biāo)準(zhǔn)輸入流
* Gzip、Deflate窥翩、DeflateRaw 數(shù)據(jù)壓縮
*
* 觸發(fā)事件:
* readable 數(shù)據(jù)可讀時(shí)
* data 數(shù)據(jù)讀取后
* end 數(shù)據(jù)讀取完成時(shí)
* error 數(shù)據(jù)讀取錯(cuò)誤時(shí)
* close 關(guān)閉流對(duì)象時(shí)
*
* 讀取數(shù)據(jù)的對(duì)象操作方法:
* read 讀取數(shù)據(jù)方法
* setEncoding 設(shè)置讀取數(shù)據(jù)的編
* pause 通知對(duì)象眾目停止觸發(fā)data事件
* resume 通知對(duì)象恢復(fù)觸發(fā)data事件
* pipe 設(shè)置數(shù)據(jù)通道业岁,將讀入流數(shù)據(jù)接入寫(xiě)入流;
* unpipe 取消通道
* unshift 當(dāng)流數(shù)據(jù)綁定一個(gè)解析器時(shí)寇蚊,此方法取消解析器
*
* ------------------------流寫(xiě)入-------------------------------------
* 寫(xiě)數(shù)據(jù)對(duì)象:
* fs.WriteStream 寫(xiě)入文件對(duì)象
* http.clientRequest 寫(xiě)入HTTP客戶端請(qǐng)求數(shù)據(jù)
* http.ServerResponse 寫(xiě)入HTTP服務(wù)器端響應(yīng)數(shù)據(jù)
* net.Socket 讀寫(xiě)TCP流或UNIX流笔时,需要connection事件傳遞給用戶
* child.stdout 子進(jìn)程標(biāo)準(zhǔn)輸出
* child.stdin 子進(jìn)程標(biāo)準(zhǔn)入
* Gzip、Deflate仗岸、DeflateRaw 數(shù)據(jù)壓縮
*
* 寫(xiě)入數(shù)據(jù)觸發(fā)事件:
* drain 當(dāng)write方法返回false時(shí)允耿,表示緩存區(qū)中已經(jīng)輸出到目標(biāo)對(duì)象中,可以繼續(xù)寫(xiě)入數(shù)據(jù)到緩存區(qū)
* finish 當(dāng)end方法調(diào)用扒怖,全部數(shù)據(jù)寫(xiě)入完成
* pipe 當(dāng)用于讀取數(shù)據(jù)的對(duì)象的pipe方法被調(diào)用時(shí)
* unpipe 當(dāng)unpipe方法被調(diào)用
* error 當(dāng)發(fā)生錯(cuò)誤
*
* 寫(xiě)入數(shù)據(jù)方法:
* write 用于寫(xiě)入數(shù)據(jù)
* end 結(jié)束寫(xiě)入右犹,之后再寫(xiě)入會(huì)報(bào)錯(cuò);
*/
20姚垃、創(chuàng)建讀取流
//fs.createReadStream(path, [options])
/**
* path 文件路徑
* [options] flags:指定文件操作,默認(rèn)'r',讀操作盼忌;encoding,指定讀取流編碼积糯;autoClose, 是否讀取完成后自動(dòng)關(guān)閉掂墓,默認(rèn)true;start指定文件開(kāi)始讀取位置看成;end指定文件開(kāi)始讀結(jié)束位置
*/
var rs = fs.createReadStream(__dirname + '/test.txt', {start: 0, end: 2});
//open是ReadStream對(duì)象中表示文件打開(kāi)時(shí)事件君编,
rs.on('open', function (fd) {
console.log('開(kāi)始讀取文件');
});
rs.on('data', function (data) {
console.log(data.toString());
});
rs.on('end', function () {
console.log('讀取文件結(jié)束')
});
rs.on('close', function () {
console.log('文件關(guān)閉');
});
rs.on('error', function (err) {
console.error(err);
});
//暫停和回復(fù)文件讀取川慌;
rs.on('open', function () {
console.log('開(kāi)始讀取文件');
});
rs.pause();
rs.on('data', function (data) {
console.log(data.toString());
});
setTimeout(function () {
rs.resume();
}, 2000);
21吃嘿、創(chuàng)建寫(xiě)入流
//fs.createWriteStream(path, [options])
/**
* path 文件路徑
* [options] flags:指定文件操作,默認(rèn)'w',梦重;encoding,指定讀取流編碼兑燥;start指定寫(xiě)入文件的位置
*/
/* ws.write(chunk, [encoding], [callback]);
* chunk, 可以為Buffer對(duì)象或一個(gè)字符串,要寫(xiě)入的數(shù)據(jù)
* [encoding], 編碼
* [callback], 寫(xiě)入后回調(diào)
*/
/* ws.end([chunk], [encoding], [callback]);
* [chunk], 要寫(xiě)入的數(shù)據(jù)
* [encoding], 編碼
* [callback], 寫(xiě)入后回調(diào)
*/
var ws = fs.createWriteStream(__dirname + '/test.txt', {start: 0});
var buffer = new Buffer('我也喜歡你');
ws.write(buffer, 'utf8', function (err, buffer) {
console.log(arguments);
console.log('寫(xiě)入完成琴拧,回調(diào)函數(shù)沒(méi)有參數(shù)')
});
//最后再寫(xiě)入的內(nèi)容
ws.end('再見(jiàn)');
//使用流完成復(fù)制文件操作
var rs = fs.createReadStream(__dirname + '/test.txt')
var ws = fs.createWriteStream(__dirname + '/test/test.txt');
rs.on('data', function (data) {
ws.write(data)
});
ws.on('open', function (fd) {
console.log('要寫(xiě)入的數(shù)據(jù)文件已經(jīng)打開(kāi)降瞳,文件描述符是: ' + fd);
});
rs.on('end', function () {
console.log('文件讀取完成');
ws.end('完成', function () {
console.log('文件全部寫(xiě)入完成')
});
});
//關(guān)于WriteStream對(duì)象的write方法返回一個(gè)布爾類型,當(dāng)緩存區(qū)中數(shù)據(jù)全部寫(xiě)滿時(shí)蚓胸,返回false;
//表示緩存區(qū)寫(xiě)滿挣饥,并將立即輸出到目標(biāo)對(duì)象中
//第一個(gè)例子
var ws = fs.createWriteStream(__dirname + '/test/test.txt');
for (var i = 0; i < 10000; i++) {
var w_flag = ws.write(i.toString());
//當(dāng)緩存區(qū)寫(xiě)滿時(shí),輸出false
console.log(w_flag);
}
//第二個(gè)例子
var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');
var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');
rs.on('data', function (data) {
var flag = ws.write(data);
console.log(flag);
});
//系統(tǒng)緩存區(qū)數(shù)據(jù)已經(jīng)全部輸出觸發(fā)drain事件
ws.on('drain', function () {
console.log('系統(tǒng)緩存區(qū)數(shù)據(jù)已經(jīng)全部輸出沛膳。')
});
22扔枫、管道pipe實(shí)現(xiàn)流讀寫(xiě)
//rs.pipe(destination, [options]);
/**
* destination 必須一個(gè)可寫(xiě)入流數(shù)據(jù)對(duì)象
* [opations] end 默認(rèn)為true,表示讀取完成立即關(guān)閉文件锹安;
*/
var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');
var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');
rs.pipe(ws);
rs.on('data', function (data) {
console.log('數(shù)據(jù)可讀')
});
rs.on('end', function () {
console.log('文件讀取完成');
//ws.end('再見(jiàn)')
});