如何用node.js作為后臺(tái),讀寫xml文件,Node.js的文件系統(tǒng)的Api
更新時(shí)間:2024年08月29日 08:39:03 作者:IT博客技術(shù)分享
這篇文章主要介紹了如何用node.js作為后臺(tái),讀寫xml文件,Node.js的文件系統(tǒng)的Api,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
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+ 讀寫;w+ 讀寫,文件不存在則創(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、寫文件
// fs.writeFile(filename,data,[options],callback); var w_data = '這是一段通過fs.writeFile函數(shù)寫入的內(nèi)容;\r\n'; var w_data = new Buffer(w_data); /** * filename, 必選參數(shù),文件名 * data, 寫入的數(shù)據(jù),可以字符或一個(gè)Buffer對象 * [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('寫入成功'); } });
3、以追加方式寫文件
// fs.appendFile(filename,data,[options],callback); fs.appendFile(__dirname + '/test.txt', '使用fs.appendFile追加文件內(nèi)容', function () { console.log('追加內(nèi)容完成'); });
4、打開文件
// fs.open(filename, flags, [mode], callback); /** * filename, 必選參數(shù),文件名 * flags, 操作標(biāo)識(shí),如"r",讀方式打開 * [mode],權(quán)限,如777,表示任何用戶讀寫可執(zhí)行 * callback 打開文件后回調(diào)函數(shù),參數(shù)默認(rèn)第一個(gè)err,第二個(gè)fd為一個(gè)整數(shù),表示打開文件返回的文件描述符,window中又稱文件句柄 */ fs.open(__dirname + '/test.txt', 'r', '0666', function (err, fd) { console.log(fd); });
5、讀文件,讀取打開的文件內(nèi)容到緩沖區(qū)中
//fs.read(fd, buffer, offset, length, position, callback); /** * fd, 使用fs.open打開成功后返回的文件描述符 * buffer, 一個(gè)Buffer對象,v8引擎分配的一段內(nèi)存 * offset, 整數(shù),向緩存區(qū)中寫入時(shí)的初始位置,以字節(jié)為單位 * length, 整數(shù),讀取文件的長度 * position, 整數(shù),讀取文件初始位置;文件大小以字節(jié)為單位 * callback(err, bytesRead, buffer), 讀取執(zhí)行完成后回調(diào)函數(shù),bytesRead實(shí)際讀取字節(jié)數(shù),被讀取的緩存區(qū)對象 */ 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、寫文件,將緩沖區(qū)內(nèi)數(shù)據(jù)寫入使用fs.open打開的文件
//fs.write(fd, buffer, offset, length, position, callback); /** * fd, 使用fs.open打開成功后返回的文件描述符 * buffer, 一個(gè)Buffer對象,v8引擎分配的一段內(nèi)存 * offset, 整數(shù),從緩存區(qū)中讀取時(shí)的初始位置,以字節(jié)為單位 * length, 整數(shù),從緩存區(qū)中讀取數(shù)據(jù)的字節(jié)數(shù) * position, 整數(shù),寫入文件初始位置; * callback(err, written, buffer), 寫入操作執(zhí)行完成后回調(diào)函數(shù),written實(shí)際寫入字節(jié)數(shù),buffer被讀取的緩存區(qū)對象 */ fs.open(__dirname + '/test.txt', 'a', function (err, fd) { if(err) { console.error(err); return; } else { var buffer = new Buffer('寫入文件數(shù)據(jù)內(nèi)容'); //寫入'入文件'三個(gè)字 fs.write(fd, buffer, 3, 9, 12, function (err, written, buffer) { if(err) { console.log('寫入文件失敗'); console.error(err); return; } else { console.log(buffer.toString()); //寫入'數(shù)據(jù)內(nèi)'三個(gè)字 fs.write(fd, buffer, 12, 9, null, function (err, written, buffer) { console.log(buffer.toString()); }) } }); } });
7、刷新緩存區(qū)
// 使用fs.write寫入文件時(shí),操作系統(tǒng)是將數(shù)據(jù)讀到內(nèi)存,再把數(shù)據(jù)寫入到文件中,當(dāng)數(shù)據(jù)讀完時(shí)并不代表數(shù)據(jù)已經(jīng)寫完,因?yàn)橛幸徊糠诌€可能在內(nèi)在緩沖區(qū)內(nèi)。 // 因此可以使用fs.fsync方法將內(nèi)存中數(shù)據(jù)寫入文件;--刷新內(nèi)存緩沖區(qū); //fs.fsync(fd, [callback]) /** * fd, 使用fs.open打開成功后返回的文件描述符 * [callback(err, written, buffer)], 寫入操作執(zhí)行完成后回調(diào)函數(shù),written實(shí)際寫入字節(jié)數(shù),buffer被讀取的緩存區(qū)對象 */ fs.open(__dirname + '/test.txt', 'a', function (err, fd) { if(err) throw err; var buffer = new Buffer('我愛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ò)誤對象 */ fs.mkdir(__dirname + '/fsDir', function (err) { if(err) throw err; console.log('創(chuàng)建目錄成功') });
9、讀取目錄
//使用fs.readdir讀取目錄,重點(diǎn)其回調(diào)函數(shù)中files對象 //fs.readdir(path, callback); /** * path, 要讀取目錄的完整路徑及目錄名; * [callback(err, files)], 讀完目錄回調(diào)函數(shù);err錯(cuò)誤對象,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++) { //使用閉包無法保證讀取文件的順序與數(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ò)誤對象,stat fs.Stat一個(gè)對象實(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、修改文件訪問時(shí)間與修改時(shí)間
//fs.utimes(path, atime, mtime, callback); /** * path, 要查看目錄/文件的完整路徑及名; * atime, 新的訪問時(shí)間 * ctime, 新的修改時(shí)間 * [callback(err)], 操作完成回調(diào)函數(shù);err操作失敗對象 */ 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('訪問時(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)限:所有用戶可讀、寫, * [callback(err)], 操作完成回調(diào)函數(shù);err操作失敗對象 */ 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操作失敗對象 */ 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操作失敗對象 */ 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)視文件
//對文件進(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對象,被修改后文件,prev,一個(gè)fs.Stat對象,表示修改前對象 */ 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)視文件
//取消對文件進(jìn)行監(jiān)視 //fs.unwatchFile(filename, [listener]); /** * filename, 完整路徑及文件名; * [listener], 要取消的監(jiān)聽器事件,如果不指定,則取消所有監(jiān)聽處理事件 */ var listener = function (curr, prev) { console.log('我是監(jiān)視函數(shù)') } fs.unwatchFile(__dirname + '/test.txt', listener);
18、監(jiān)視文件或目錄
// 對文件或目錄進(jìn)行監(jiān)視,并且在監(jiān)視到修改時(shí)執(zhí)行處理; // fs.watch返回一個(gè)fs.FSWatcher對象,擁有一個(gè)close方法,用于停止watch操作; // 當(dāng)fs.watch有文件變化時(shí),會(huì)觸發(fā)fs.FSWatcher對象的change(err, filename)事件,err錯(cuò)誤對象,filename發(fā)生變化的文件名 // fs.watch(filename, [options], [listener]); /** * filename, 完整路徑及文件名或目錄名; * [listener(event, filename], 監(jiān)聽器事件,有兩個(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接口的對象進(jìn)行流數(shù)據(jù)讀寫;以上接口都繼承自EventEmitter類,因此在讀/寫流不同狀態(tài)時(shí),觸發(fā)不同事件; * 關(guān)于流讀取:Node.js不斷將文件一小塊內(nèi)容讀入緩沖區(qū),再從緩沖區(qū)中讀取內(nèi)容; * 關(guān)于流寫入:Node.js不斷將流數(shù)據(jù)寫入內(nèi)在緩沖區(qū),待緩沖區(qū)滿后再將緩沖區(qū)寫入到文件中;重復(fù)上面操作直到要寫入內(nèi)容寫寫完; * readFile、read、writeFile、write都是將整個(gè)文件放入內(nèi)存而再操作,而則是文件一部分?jǐn)?shù)據(jù)一部分?jǐn)?shù)據(jù)操作; * * -----------------------流讀取------------------------------------- * 讀取數(shù)據(jù)對象: * fs.ReadStream 讀取文件 * http.IncomingMessage 客戶端請求或服務(wù)器端響應(yīng) * net.Socket Socket端口對象 * 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)閉流對象時(shí) * * 讀取數(shù)據(jù)的對象操作方法: * read 讀取數(shù)據(jù)方法 * setEncoding 設(shè)置讀取數(shù)據(jù)的編 * pause 通知對象眾目停止觸發(fā)data事件 * resume 通知對象恢復(fù)觸發(fā)data事件 * pipe 設(shè)置數(shù)據(jù)通道,將讀入流數(shù)據(jù)接入寫入流; * unpipe 取消通道 * unshift 當(dāng)流數(shù)據(jù)綁定一個(gè)解析器時(shí),此方法取消解析器 * * ------------------------流寫入------------------------------------- * 寫數(shù)據(jù)對象: * fs.WriteStream 寫入文件對象 * http.clientRequest 寫入HTTP客戶端請求數(shù)據(jù) * http.ServerResponse 寫入HTTP服務(wù)器端響應(yīng)數(shù)據(jù) * net.Socket 讀寫TCP流或UNIX流,需要connection事件傳遞給用戶 * child.stdout 子進(jìn)程標(biāo)準(zhǔn)輸出 * child.stdin 子進(jìn)程標(biāo)準(zhǔn)入 * Gzip、Deflate、DeflateRaw 數(shù)據(jù)壓縮 * * 寫入數(shù)據(jù)觸發(fā)事件: * drain 當(dāng)write方法返回false時(shí),表示緩存區(qū)中已經(jīng)輸出到目標(biāo)對象中,可以繼續(xù)寫入數(shù)據(jù)到緩存區(qū) * finish 當(dāng)end方法調(diào)用,全部數(shù)據(jù)寫入完成 * pipe 當(dāng)用于讀取數(shù)據(jù)的對象的pipe方法被調(diào)用時(shí) * unpipe 當(dāng)unpipe方法被調(diào)用 * error 當(dāng)發(fā)生錯(cuò)誤 * * 寫入數(shù)據(jù)方法: * write 用于寫入數(shù)據(jù) * end 結(jié)束寫入,之后再寫入會(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指定文件開始讀取位置;end指定文件開始讀結(jié)束位置 */ var rs = fs.createReadStream(__dirname + '/test.txt', {start: 0, end: 2}); //open是ReadStream對象中表示文件打開時(shí)事件, rs.on('open', function (fd) { console.log('開始讀取文件'); }); 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('開始讀取文件'); }); rs.pause(); rs.on('data', function (data) { console.log(data.toString()); }); setTimeout(function () { rs.resume(); }, 2000);
21、創(chuàng)建寫入流
//fs.createWriteStream(path, [options]) /** * path 文件路徑 * [options] flags:指定文件操作,默認(rèn)'w',;encoding,指定讀取流編碼;start指定寫入文件的位置 */ /* ws.write(chunk, [encoding], [callback]); * chunk, 可以為Buffer對象或一個(gè)字符串,要寫入的數(shù)據(jù) * [encoding], 編碼 * [callback], 寫入后回調(diào) */ /* ws.end([chunk], [encoding], [callback]); * [chunk], 要寫入的數(shù)據(jù) * [encoding], 編碼 * [callback], 寫入后回調(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('寫入完成,回調(diào)函數(shù)沒有參數(shù)') }); //最后再寫入的內(nèi)容 ws.end('再見'); //使用流完成復(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('要寫入的數(shù)據(jù)文件已經(jīng)打開,文件描述符是: ' + fd); }); rs.on('end', function () { console.log('文件讀取完成'); ws.end('完成', function () { console.log('文件全部寫入完成') }); }); //關(guān)于WriteStream對象的write方法返回一個(gè)布爾類型,當(dāng)緩存區(qū)中數(shù)據(jù)全部寫滿時(shí),返回false; //表示緩存區(qū)寫滿,并將立即輸出到目標(biāo)對象中 //第一個(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ū)寫滿時(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)流讀寫
//rs.pipe(destination, [options]); /** * destination 必須一個(gè)可寫入流數(shù)據(jù)對象 * [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é)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
實(shí)例分析nodejs模塊xml2js解析xml過程中遇到的坑
這篇文章主要介紹了實(shí)例分析nodejs模塊xml2js解析xml過程中遇到的坑,涉及nodejs模塊xml2js解析xml過程中parseString方法參數(shù)使用技巧,需要的朋友可以參考下2017-03-03webstorm配置支持nodejs并自動(dòng)補(bǔ)全的方法
今天小編就為大家分享一篇webstorm配置支持nodejs并自動(dòng)補(bǔ)全的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05解決npm?i?報(bào)錯(cuò)以及python安裝卡住的問題
這篇文章主要介紹了解決npm?i?報(bào)錯(cuò)以及python安裝卡住的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié)
這篇文章主要介紹了nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié),對FS模塊的大部份異步函數(shù)做了介紹,而且用中文注釋,這下用起來方便了,需要的朋友可以參考下2014-06-06node.js實(shí)現(xiàn)websocket的即時(shí)通訊詳解
這篇文章主要介紹了深入淺出講解websocket的即時(shí)通訊,服務(wù)器可以主動(dòng)向客戶端推送信息,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種,需要的朋友可以參考下2023-05-05