tft每日頭條

 > 科技

 > node有哪些知識

node有哪些知識

科技 更新时间:2025-05-02 06:28:42

今天我們主要來介紹下Node體系中的文件系統。

node有哪些知識(Node知識體系之文件系統)1

fs 模塊交互的幾種方式
  • POSIX 文件 I/O
  • 文件流
  • 批量文件 I/O
  • 文件監控
POSIX 文件系統

node有哪些知識(Node知識體系之文件系統)2

node有哪些知識(Node知識體系之文件系統)3

代碼示例:

const fs = require('fs'); const assert = require('assert'); const fd = fs.openSync('./file.txt', 'w '); const writeBuf = new Buffer('some data to write'); fs.writeSync(fd, writeBuf, 0, writeBuf.length, 0); const readBuf = new Buffer(writeBuf.length); fs.readSync(fd, readBuf, 0, writeBuf.length, 0); assert.equal(writeBuf.toString(), readBuf.toString()); fs.closeSync(fd);

讀寫流

const fs = require('fs'); const readable = fs.createReadStream('./original.txt'); const writeable = fs.createWriteStream('./copy.txt'); readable.pipe(writeable);

文件監控

fs.watchFile 比 fs.watch 低效,但更好用。

同步讀取與 require

同步 fs 的方法應該在第一次初始化應用的時候使用。

const fs = require('fs'); const config = JSON.parse(fs.readFileSync('./config.json').toString()); init(config);

require:

const config = require('./config.json); init(config);

  • 模塊會被全局緩沖,其他文件也加載并修改,會影響到整個系統加載了此文件的模塊
  • 可以通過 Object.freeze 來凍結一個對象
文件描述

文件描述是在操作系統中管理的在進程中打開文件所關聯的一些數字或者索引。操作系統通過指派一個唯一的整數給每個打開的文件用來查看關于這個文件。

node有哪些知識(Node知識體系之文件系統)4

console.log('log') 是 process.stdout.write('log') 的語法糖。

一個文件描述是 open 以及 openSync 方法調用返回的一個數字

const fd = fs.openSync('myfile', 'a'); console.log(typeof fd === 'number'); // true

文件鎖

協同多個進程同時訪問一個文件,保證文件的完整性以及數據不能丢失:

  • 強制鎖(在内核級别執行)
  • 咨詢鎖(非強制,隻在涉及到進程訂閱了相同的鎖機制)
  • node-fs-ext 通過 flock 鎖住一個文件
  • 使用鎖文件
  • 進程 A 嘗試創建一個鎖文件,并且成功了
  • 進程 A 已經獲得了這個鎖,可以修改共享的資源
  • 進程 B 嘗試創建一個鎖文件,但失敗了,無法修改共享的資源

Node 實現鎖文件

  • 使用獨占标記創建鎖文件
  • 使用 mkdir 創建鎖文件

獨占标記

// 所有需要打開文件的方法,fs.writeFile、fs.createWriteStream、fs.open 都有一個 x 标記 // 這個文件應該已獨占打開,若這個文件存在,文件不能被打開 fs.open('config.lock', 'wx', (err) => { if (err) { return console.err(err); } }); // 最好将當前進程号寫進文件鎖中 // 當有異常的時候就知道最後這個鎖的進程 fs.writeFile( 'config.lock', process.pid, { flogs: 'wx' }, (err) => { if (err) { return console.error(err) }; }, );

mkdir 文件鎖

獨占标記有個問題,可能有些系統不能識别 0_EXCL 标記。另一個方案是把鎖文件換成一個目錄,PID 可以寫入目錄中的一個文件。

fs.mkidr('config.lock', (err) => { if (err) { return console.error(err); } fs.writeFile(`/config.lock/${process.pid}`, (err) => { if (err) { return console.error(err); } }); });

lock 模塊實現

const fs = require('fs'); const lockDir = 'config.lock'; let hasLock = false; exports.lock = function (cb) { // 獲取鎖 if (hasLock) { return cb(); } // 已經獲取了一個鎖 fs.mkdir(lockDir, function (err) { if (err) { return cb(err); } // 無法創建鎖 fs.writeFile(lockDir '/' process.pid, function (err) { // 把 PID寫入到目錄中以便調試 if (err) { console.error(err); } // 無法寫入 PID,繼續運行 hasLock = true; // 鎖創建了 return cb(); }); }); }; exports.unlock = function (cb) { // 解鎖方法 if (!hasLock) { return cb(); } // 如果沒有需要解開的鎖 fs.unlink(lockDir '/' process.pid, function (err) { if (err) { return cb(err); } fs.rmdir(lockDir, function (err) { if (err) return cb(err); hasLock = false; cb(); }); }); }; process.on('exit', function () { if (hasLock) { fs.unlinkSync(lockDir '/' process.pid); // 如果還有鎖,在退出之前同步删除掉 fs.rmdirSync(lockDir); console.log('removed lock'); } });

遞歸文件操作

推薦一個線上庫:mkdirp

遞歸:要解決我們的問題就要先解決更小的相同的問題。

dir-a ├── dir-b │ ├── dir-c │ │ ├── dir-d │ │ │ └── file-e.png │ │ └── file-e.png │ ├── file-c.js │ └── file-d.txt ├── file-a.js └── file-b.txt

查找模塊:find /asset/dir-a -name="file.*"

[ 'dir-a/dir-b/dir-c/dir-d/file-e.png', 'dir-a/dir-b/dir-c/file-e.png', 'dir-a/dir-b/file-c.js', 'dir-a/dir-b/file-d.txt', 'dir-a/file-a.js', 'dir-a/file-b.txt', ] const fs = require('fs'); const join = require('path').join; // 同步查找 exports.findSync = function (nameRe, startPath) { const results = []; function finder(path) { const files = fs.readdirSync(path); for (let i = 0; i < files.length; i ) { const fpath = join(path, files[i]); const stats = fs.statSync(fpath); if (stats.isDirectory()) { finder(fpath); } if (stats.isFile() && nameRe.test(files[i])) { results.push(fpath); } } } finder(startPath); return results; }; // 異步查找 exports.find = function (nameRe, startPath, cb) { // cb 可以傳入 console.log,靈活 const results = []; let asyncOps = 0; // 2 function finder(path) { asyncOps ; fs.readdir(path, function (er, files) { if (er) { return cb(er); } files.forEach(function (file) { const fpath = join(path, file); asyncOps ; fs.stat(fpath, function (er, stats) { if (er) { return cb(er); } if (stats.isDirectory()) finder(fpath); if (stats.isFile() && nameRe.test(file)) { results.push(fpath); } asyncOps--; if (asyncOps == 0) { cb(null, results); } }); }); asyncOps--; if (asyncOps == 0) { cb(null, results); } }); } finder(startPath); }; console.log(exports.findSync(/file.*/, `${__dirname}/dir-a`)); console.log(exports.find(/file.*/, `${__dirname}/dir-a`, console.log));

監視文件和文件夾

想要監聽一個文件或者目錄,并在文件更改後執行一個動作。

const fs = require('fs'); fs.watch('./watchdir', console.log); // 穩定且快 fs.watchFile('./watchdir', console.log); // 跨平台

逐行地讀取文件流

const fs = require('fs'); const readline = require('readline'); const rl = readline.createInterface({ input: fs.createReadStream('/etc/hosts'), crlfDelay: Infinity }); rl.on('line', (line) => { console.log(`cc ${line}`); const extract = line.match(/(\d \.\d \.\d \.\d ) (.*)/); });

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved