參考:https://www.runoob.com/nodejs/nodejs-fs.html
異步I/O 1,文件操作 2,網絡操作
在瀏覽器中也存在異步操作 1,定時任務 2,事件處理 3,Ajax回調處理
js的運行是單線程的,引入事件隊列機制,進入事件隊列的任務主要分兩種: Node.js中異步執行的任務:1,文件讀寫操作(文件I/O) 2,網絡的請求相應處理(網絡I/O)
Node.js中的事件模型與瀏覽器中的事件模型類型:單線程+事件隊列,js的運行是單線程的,Node.js的環境是多線程的
一、獲取文件信息
通過異步模式獲取文件信息的語法格式
fs.stat(path, callback)
fs.stat(path)執行后,會將stats類的實例返回給其回調函數。可以通過stats類中的提供方法判斷文件的相關屬性。例如判斷是否為文件:
常用方法:
| stats.isFile() | 如果是文件返回 true,否則返回 false。 |
| stats.isDirectory() | 如果是目錄返回 true,否則返回 false。 |
var fs = require('fs'); fs.stat('01.js', function(err, stats) { if(err) return; console.log(stats); if(stats.isFile()){ console.log('文件'); } else if(stats.isDirectory()){ console.log('目錄'); } });
返回結果:
atime 文件訪問時間
ctime 文件狀態信息發生變化的時間,比如文件的權限
mtime文件數據發生變化的時間
birthtime文件創建時間
Stats { dev: 3963844000, mode: 33206, nlink: 1, uid: 0, gid: 0, rdev: 0, blksize: 4096, ino: 7599824371308861, size: 326, blocks: 0, atimeMs: 1621577436001.767, mtimeMs: 1621577434724.8518, ctimeMs: 1621577434728.6726, birthtimeMs: 1621505236836.661, atime: 2021-05-21T06:10:36.002Z, mtime: 2021-05-21T06:10:34.725Z, ctime: 2021-05-21T06:10:34.729Z, birthtime: 2021-05-20T10:07:16.837Z }
文件
二、讀文件操作
var path = require('path'); var strpath = path.join(__dirname, '02.json'); // 如果沒有設置編碼方式,那么得到的是Buffer對象,需要進行轉換 fs.readFile(strpath, 'utf-8', function(err, data){ console.log(data); });
三、寫文件操作
異步模式下寫入文件的語法格式:
fs.writeFile(file, data[, options], callback)
writeFile 直接打開文件默認是 w 模式,所以如果文件存在,該方法寫入的內容會覆蓋舊的文件內容。
var fs = require("fs"); console.log("准備寫入文件"); fs.writeFile('input.txt', '我是通 過fs.writeFile 寫入文件的內容', function(err) { if (err) { return console.error(err); } console.log("數據寫入成功!"); console.log("--------我是分割線-------------") console.log("讀取寫入的數據!"); fs.readFile('input.txt', function (err, data) { if (err) { return console.error(err); } console.log("異步讀取文件數據: " + data.toString()); }); });
執行結果:
$ node file.js 准備寫入文件 數據寫入成功! --------我是分割線------------- 讀取寫入的數據! 異步讀取文件數據: 我是通 過fs.writeFile 寫入文件的內容
四、大文件操作(流式操作)
這個只能處理內容量較少的文件,會讀取全部內容,將內容加載到內存
fs.createReadStream(path[, options]) 返回ReadStream 對象。
fs.createWriteStream(path[, options]) 返回 WriteStream 對象。
var path = require('path'); var fs = require('fs'); // 源路徑 var spath = path.join(__dirname, '../doc', 'css.md'); // 目標路徑 var dpath = path.join('D:\\Users\\peiyuli\\Desktop', 'css.md'); var readStream = fs.createReadStream(spath); var writeStream = fs.createWriteStream(dpath); var sum = 0; // 基於事件的處理方式 以chunk(塊)為單位,每次讀取文件大小時會觸發data事件 readStream.on('data', function(chunk){ sum++; writeStream.write(chunk); }); // 數據處理完成標志 end事件 readStream.on('end', function(){ console.log('文件處理完成', sum); });
方法二、簡化流程
var path = require('path'); var fs = require('fs'); // 源路徑 var spath = path.join(__dirname, '../doc', 'css.md'); // 目標路徑 var dpath = path.join('D:\\Users\\peiyuli\\Desktop', 'css.md'); // 管道方法 將讀取流和寫入流融合到一塊 fs.createReadStream(spath).pipe(fs.createWriteStream(dpath));
五、目錄的操作
fs.mkdir(path[, options], callback) 創建目錄
fs.mkdir(path.join(__dirname, 'abc'), function(err){ console.log(err); });
執行結果:生成了abc目錄

fs.readdir(path[, options], callback) 讀取目錄
var path = require('path'); var fs = require('fs'); fs.readdir(__dirname, function(err, files){ console.log(files); files.forEach(function(item, index){ // 獲取文件信息 fs.stat(path.join(__dirname, item), function(err, stat){ // 判斷是否為文件 if(stat.isFile()){ console.log(item, '文件'); } else if(stat.isDirectory()){ // 判斷是否為目錄 console.log(item, '目錄'); } }); }); });
執行結果:

fs.rmdir(path[, options], callback) 刪除目錄
fs.rmdir(path.join(__dirname, 'abc'), function(err){ console.log(err); });
