環境:Node v8.2.1; Npm v5.3.0; OS Windows10html
nodejs的文件操做大部分API都提供了同步和異步的兩種方式,下面是異步API結構圖,同步方法在異步方法後面加【Sync】就好了node
下面是部分API的例子,對部分API的一個簡單代碼實現json
//readFile(filename,[options],callback); /** * filename, 必選參數,文件名 * [options],可選參數,可指定flag(文件操做選項,如r+ 讀寫;w+ 讀寫,文件不存在則建立)及encoding屬性 * callback 讀取文件後的回調函數,參數默認第一個err,第二個data 數據 */ const fs = require("fs"); fs.readFile('./package.json',{flag:"r+",encoding:"utf8"},(err,data)=>{ if(err) throw err; console.log(data); })
// fs.writeFile(filename,data,[options],callback); /** * filename, 必選參數,文件名 * data, 寫入的數據,能夠字符或一個Buffer對象 * [options],flag,mode(權限),encoding * callback 讀取文件後的回調函數,參數默認第一個err,第二個data 數據 */ const fs = require("fs"); const data="hello world"; const bf=Buffer.from(data); //buffer寫入 fs.writeFile("./test.txt",bf,err=>{ if(err) throw err; console.log("寫入成功"); }) //字符寫入 fs.writeFile("./test.txt",data,err=>{ if(err) throw err; console.log("寫入成功"); })
// fs.appendFile(filename,data,[options],callback); const fs = require("fs"); const data = " hello world"; const bf = Buffer.from(data); //buffer fs.appendFile("./test.txt", bf, err => { if (err) throw err; console.log("追加成功"); }) fs.appendFile("./test.txt", data, err => { if (err) throw err; console.log("追加成功"); })
打開文件,獲取文件描述數組
// fs.open(filename, flags, [mode], callback); /** * filename, 必選參數,文件名 * flags, 操做標識,如"r",讀方式打開 * [mode],權限,如777,表示任何用戶讀寫可執行 * callback 打開文件後回調函數,參數默認第一個err,第二個fd爲一個整數,表示打開文件返回的文件描述符,window中又稱文件句柄 */ const fs = require("fs"); fs.open("./test.txt","r",0666,(err,fd)=>{ if(err) throw err; console.log(fd); //3 })
【0666】爲【文件權限碼】,也能夠在【fs.constants】中輸出緩存
//fs.read(fd, buffer, offset, length, position, callback); /** * fd, 使用fs.open打開成功後返回的文件描述符 * buffer, 一個Buffer對象,v8引擎分配的一段內存 * offset, 整數,向緩存區中寫入時的初始位置,以字節爲單位 * length, 整數,讀取文件的長度 * position, 整數,讀取文件初始位置;文件大小以字節爲單位 * callback(err, bytesRead, buffer), 讀取執行完成後回調函數,bytesRead實際讀取字節數,被讀取的緩存區對象 */ const fs = require("fs"); fs.open("./test.txt", "r", (err, fd) => { if (err) throw err; let bf = Buffer.alloc(255); fs.read(fd,bf,0,9,0,(err,bytesRead,buffer)=>{ if(err) throw err; console.log(bytesRead); console.log(buffer.toString()); }) })
//fs.write(fd, buffer, offset, length, position, callback); /** * fd, 使用fs.open打開成功後返回的文件描述符 * buffer, 一個Buffer對象,v8引擎分配的一段內存 * offset, 整數,從緩存區中讀取時的初始位置,以字節爲單位 * length, 整數,從緩存區中讀取數據的字節數 * position, 整數,寫入文件初始位置; * callback(err, written, buffer), 寫入操做執行完成後回調函數,written實際寫入字節數,buffer被讀取的緩存區對象 */ const fs = require("fs"); fs.open("./test.txt", "w", (err, fd) => { if (err) throw err; let bf = Buffer.from(" 寫入文件數據的內容"); fs.write(fd, bf, 0, bf.length, 0, (err, bytesWritten, buffer) => { if (err) throw err; console.log(bytesWritten); console.log(`寫入的內容:${buffer.toString()}`); }) })
使用fs.write寫入文件時,操做系統是將數據讀到內存,再把數據寫入到文件中,當數據讀完時並不表明數據已經寫完,由於有一部分還可能在內在緩衝區內。
所以可使用fs.fsync方法將內存中數據寫入文件;--刷新內存緩衝區;app
//fs.fsync(fd, [callback]) /** * fd, 使用fs.open打開成功後返回的文件描述符 * [callback(err, written, buffer)], 寫入操做執行完成後回調函數,written實際寫入字節數,buffer被讀取的緩存區對象 */ const fs = require("fs"); fs.open("./test.txt", "a+", (err, fd) => { if (err) throw err; let bf = Buffer.from(" I love Node"); fs.write(fd, bf, 0, bf.length, 0, (err, bytesWritten, buffer) => { if (err) throw err; fs.fsync(fd,(err)=>{}); fs.close(fd,err=>{}); }) })
//使用fs.readdir讀取目錄,重點其回調函數中files對象 //fs.readdir(path, callback); /** * path, 要讀取目錄的完整路徑及目錄名; * [callback(err, files)], 讀完目錄回調函數;err錯誤對象,files數組,存放讀取到的目錄中的全部文件名 */ const fs = require("fs"), path = require("path"); fs.readdir(__dirname + "/../11文件系統fs", (err, files) => { if (err) throw err; files.forEach(file => { let filePath = path.normalize(__dirname + '/' + file); fs.stat(filePath, (err, stats) => { if (stats.isFile()) { console.log(filePath + ' is: ' + 'file'); } if (stats.isDirectory()) { console.log(filePath + ' is: ' + 'dir'); } }) }) })
//fs.createReadStream(path, [options]) /** * path 文件路徑 * [options] flags:指定文件操做,默認'r',讀操做;encoding,指定讀取流編碼;autoClose, 是否讀取完成後自動關閉,默認true;start指定文件開始讀取位置;end指定文件開始讀結束位置 */ const fs = require("fs"); const rs = fs.createReadStream("./package.json", { flags: "r" }); rs.on("open", fd => console.log('開始讀取文件')); rs.on('data', data => { console.log(data.toString()); }) rs.on('end', function () { console.log('讀取文件結束') }); rs.on('close', function () { console.log('文件關閉'); }); rs.on('error', function (err) { console.error(err); });
//fs.createWriteStream(path, [options]) /** * path 文件路徑 * [options] flags:指定文件操做,默認'w',;encoding,指定讀取流編碼;start指定寫入文件的位置 */ /* ws.write(chunk, [encoding], [callback]); * chunk, 能夠爲Buffer對象或一個字符串,要寫入的數據 * [encoding], 編碼 * [callback], 寫入後回調 */ /* ws.end([chunk], [encoding], [callback]); * [chunk], 要寫入的數據 * [encoding], 編碼 * [callback], 寫入後回調 */ const fs = require("fs"); const ws=fs.createWriteStream("./test.txt",{flags:"w"}) const bf=Buffer.from("I Love Node"); ws.on('open', function () { console.log('文件流開啓') }); ws.on('close', function () { console.log('文件流關閉'); }); ws.on('error', function (err) { console.error(err); }); ws.write(bf,"utf8",(err,buffer)=>{ console.log('寫入完成') }) ws.end(' Bye');
流複製文件就是建立一個讀取流和一個寫入流,將讀取流中的流出的數據用寫入流進行寫入異步
//使用流複製文件 const fs = require("fs"); const rs = fs.createReadStream("./package.json"); const ws = fs.createWriteStream("./package1.json"); rs.on("data", data => { ws.write(data); }) ws.on('open', function (fd) { console.log('要寫入的數據文件已經打開,文件描述符是: ' + fd); }); rs.on("end",()=>{ console.log('文件讀取完成'); ws.end('完成',()=>{ console.log("文件寫入完成"); }) })
關於WriteStream對象的write方法返回一個布爾類型,當緩存區中數據所有寫滿時,返回false;表示緩存區已經寫滿,並將當即輸出到目標對象中。函數
一個例子測試返回值:測試
const fs = require("fs"); var ws = fs.createWriteStream(__dirname + '/test.txt',{flags:"w"}); for (var i = 0; i < 10000; i++) { var w_flag = ws.write(i.toString()); //當緩存區寫滿時,輸出false console.log(w_flag); }
一個例子當緩存區數據所有輸出時,觸發事件ui
const fs = require("fs"); const rs = fs.createReadStream("./ABoy.mp3"); const ws = fs.createWriteStream("./ABoy1.mp3"); rs.on("data", data => { let t = ws.write(data); if(!t){ console.log(t); } }) ws.on("drain", () => { console.log('系統緩存區數據已經所有輸出。') })
上面使用一個讀取流額一個寫入流進行了一次文件的複製,還有另一種方式就是在寫入流和讀取流之間創建一條管道,是讀取流中的數據經過管道源源不斷的流向寫入流,實現文件的複製。
const fs = require("fs"); const rs = fs.createReadStream("./ABoy.mp3"); const ws = fs.createWriteStream("./ABoy1.mp3"); rs.pipe(ws); rs.on('data', function (data) { console.log('數據可讀') }); rs.on('end', function () { console.log('文件讀取完成'); }); ws.on("drain", () => { console.log('系統緩存區數據已經所有輸出。') }); ws.on('open', function (fd) { console.log('要寫入的數據文件已經打開,文件描述符是: ' + fd); });
CSDN 【Node文件系統fs模塊】同步更新