日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

fsx 簡介:適用于 JavaScript 的現(xiàn)代文件系統(tǒng) API

來源: 責(zé)編: 時間:2024-01-23 17:23:02 303觀看
導(dǎo)讀JavaScript 運(yùn)行時中的文件系統(tǒng) API 已經(jīng)很久沒有這么好了,這是我試圖做出一個更好的文件系統(tǒng) API 的嘗試。我們今天擁有的 JavaScript API 比十年前要好得多。考慮一下從 XMLHttpRequest 到 fetch()的轉(zhuǎn)變:開發(fā)者體驗(yàn)

JavaScript 運(yùn)行時中的文件系統(tǒng) API 已經(jīng)很久沒有這么好了,這是我試圖做出一個更好的文件系統(tǒng) API 的嘗試。ghN28資訊網(wǎng)——每日最新資訊28at.com

ghN28資訊網(wǎng)——每日最新資訊28at.com

我們今天擁有的 JavaScript API 比十年前要好得多。考慮一下從 XMLHttpRequest 到 fetch()的轉(zhuǎn)變:開發(fā)者體驗(yàn)顯著改善,允許我們編寫更簡潔、功能性更強(qiáng)的代碼來完成同樣的事情。異步編程的 promises 的引入允許了這種變化,以及一系列其他變化,使得 JavaScript 更容易編寫。然而,有一個領(lǐng)域幾乎沒有創(chuàng)新:服務(wù)器端 JavaScript 運(yùn)行時的文件系統(tǒng) API。ghN28資訊網(wǎng)——每日最新資訊28at.com

Node.js:當(dāng)今文件系統(tǒng) API 的起源

Node.js 最初發(fā)布于 2009 年,隨之誕生了 fs 模塊。fs 模塊是圍繞 Linux 的核心實(shí)用程序構(gòu)建的,其中的許多方法都反映了它們的 Linux 靈感,如 rmdir 、 mkdir 和 stat 。為此,Node.js 成功創(chuàng)建了一個低級文件系統(tǒng) API,可以處理開發(fā)人員希望在命令行上完成的任何事情。不幸的是,這就是創(chuàng)新的終點(diǎn)。ghN28資訊網(wǎng)——每日最新資訊28at.com

Node.js 文件系統(tǒng) API 最大的改變是引入了 fs/promises ,將整個實(shí)用程序從基于回調(diào)的方法移動到基于 promise 的方法。較小的增量變化包括實(shí)現(xiàn) web 流和確保 reader 也實(shí)現(xiàn)了異步迭代器。該 API 仍然使用專有的 Buffer 類來讀取二進(jìn)制數(shù)據(jù)。(盡管 Buffer 現(xiàn)在是 Uint8Array 的子類,但仍然存在不兼容性,這使得使用 Buffers 有問題。)ghN28資訊網(wǎng)——每日最新資訊28at.com

即使是 Ryan Dhal 在 Node.js 上的繼任者 Deno,也沒有在文件系統(tǒng) API 上做太多的改進(jìn),它基本上遵循了與 Node.js 中的 fs 模塊相同的模式,盡管它使用了 Uint8Arrays,而 Node.js 使用了 Buffer s,并且在不同的地方使用了異步迭代器,但它仍然采用了與 Node.js 相同的低級 API 方法。ghN28資訊網(wǎng)——每日最新資訊28at.com

只有 Bun,作為服務(wù)器端 JavaScript 運(yùn)行時生態(tài)系統(tǒng)的最新成員,甚至嘗試使用 Bun.file() 來更新文件系統(tǒng) API,這是受 fetch() 的啟發(fā)。雖然我贊賞這種對如何使用文件的重新思考,但當(dāng)你處理多個文件時,為每個想要處理的文件創(chuàng)建一個新對象可能會很麻煩(當(dāng)處理數(shù)千個文件時,會有一個巨大的性能損失)。除此之外,Bun 希望你使用 Node.js fs 模塊進(jìn)行其他操作。ghN28資訊網(wǎng)——每日最新資訊28at.com

一個現(xiàn)代的文件系統(tǒng) API 會是什么樣子?

在花費(fèi)數(shù)年時間在維護(hù) ESLint 的同時與 Node.js fs 模塊斗爭之后,我問自己,一個現(xiàn)代的文件系統(tǒng) API 會是什么樣子?ghN28資訊網(wǎng)——每日最新資訊28at.com

  • 通常情況下會很簡單。至少 80%的時間,我不是讀取文件就是寫入文件,或者檢查文件是否存在,差不多就是這樣,然而這些操作充滿了危險(xiǎn),因?yàn)槲倚枰獧z查各種東西以避免錯誤或記住額外的屬性(例如 { encoding: "utf8" } )。
  • 錯誤將很少發(fā)生。我對 fs 模塊最大的抱怨就是它拋出錯誤的頻率。在不存在的文件上調(diào)用 fs.stat() 會拋出錯誤,這意味著你實(shí)際上需要將每個調(diào)用包裝在 try-catch 中。為什么?對于大多數(shù)應(yīng)用程序來說,缺少文件并不是不可恢復(fù)的錯誤。
  • 行動將是可觀察的。在測試文件系統(tǒng)操作時,我真的只是想要一種方法來驗(yàn)證我期望發(fā)生的事情是否確實(shí)發(fā)生了。我不想與其他一些實(shí)用程序建立間諜網(wǎng)絡(luò),這些實(shí)用程序可能會也可能不會改變我正在觀察的方法的實(shí)際行為。
  • 模擬很容易。我總是驚訝于模擬文件系統(tǒng)操作的難度。最后我只能使用 proxyquire 之類的東西,否則就需要設(shè)置迷宮般的模擬,花上一段時間才能弄好。對于文件系統(tǒng)操作來說,這是一個很常見的需求,竟然還沒有解決方案。

帶著這些想法,我開始設(shè)計(jì) fsx。ghN28資訊網(wǎng)——每日最新資訊28at.com

FSX 基礎(chǔ)知識

fsx庫是我圍繞現(xiàn)代高級文件系統(tǒng) API 應(yīng)該是什么樣子的想法的結(jié)晶。在這一點(diǎn)上,它專注于支持最常見的文件系統(tǒng)操作,而把較少使用的操作(例如 chmod )拋在后面。(我并不是說這些操作在將來不會被添加,但對我來說,從最常見的情況開始,然后以與初始方法相同的謹(jǐn)慎方式構(gòu)建更多的功能是很重要的。)ghN28資訊網(wǎng)——每日最新資訊28at.com

使用 fsx 運(yùn)行時包

首先,fsx API 在三個運(yùn)行時包中可用。這些包都包含相同的功能,但綁定到不同的底層 API。這些包是:ghN28資訊網(wǎng)——每日最新資訊28at.com

  • fsx-node - Node.js 中 fsx API 的綁定
  • fsx-deno - fsx API 的 Deno 綁定
  • fsx-memory - 適用于任何運(yùn)行時(包括 web 瀏覽器)的內(nèi)存實(shí)現(xiàn)

所以,開始時,你需要使用最適合你用例的運(yùn)行時包。為了本文的目的,我將專注于 fsx-node ,但相同的 API 存在于所有運(yùn)行時包中. 所有運(yùn)行時包都導(dǎo)出一個 fsx 單例,你可以以類似于 fs的方式使用它。ghN28資訊網(wǎng)——每日最新資訊28at.com

import { fsx } from "node-fsx";

使用 fsx 讀取文件

文件是通過使用返回特定數(shù)據(jù)類型的方法來讀取的:ghN28資訊網(wǎng)——每日最新資訊28at.com

  • fsx.text(filePath) 讀取給定的文件并返回一個字符串。
  • fsx.json(filePath) 讀取給定的文件并返回一個 JSON 值。
  • fsx.arrayBuffer(filePath) 讀取給定的文件并返回一個 ArrayBuffer 。

這里有一些例子:ghN28資訊網(wǎng)——每日最新資訊28at.com

// read plain textconst text = await fsx.text("/path/to/file.txt");// read JSONconst json = await fsx.json("/path/to/file.json");// read bytesconst bytes = await fsx.arrayBuffer("/path/to/file.png");

如果文件不存在,每個方法都會返回 undefined 而不是拋出錯誤。這意味著您可以使用 if 語句而不是 try-catch,并且可以選擇使用 nullish 合并運(yùn)算符來指定默認(rèn)值,如下所示:ghN28資訊網(wǎng)——每日最新資訊28at.com

// read plain textconst text = (await fsx.text("/path/to/file.txt")) ?? "default value";// read JSONconst json = (await fsx.json("/path/to/file.json")) ?? {};// read bytesconst bytes =  (await fsx.arrayBuffer("/path/to/file.png")) ?? new ArrayBuffer(16);

我覺得這種方法在 2024 年比不斷擔(dān)心不存在的文件出錯更有 JavaScript 風(fēng)格。ghN28資訊網(wǎng)——每日最新資訊28at.com

使用 fsx 寫文件

要寫文件,調(diào)用 fsx.write() 方法。這個方法接受兩個參數(shù):ghN28資訊網(wǎng)——每日最新資訊28at.com

  • filePath:string - 寫入的路徑
  • value:string|ArrayBuffer - 寫入文件的值

這里有一個例子:ghN28資訊網(wǎng)——每日最新資訊28at.com

// write a stringawait fsx.write("/path/to/file.txt", "Hello world!");const bytes = new TextEncoder().encode("Hello world!").buffer;// write a bufferawait fsx.write("/path/to/file.txt", buffer);

作為額外的好處,fsx.write() 將自動創(chuàng)建任何尚不存在的目錄。這是我經(jīng)常遇到的另一個問題,我認(rèn)為它應(yīng)該在現(xiàn)代文件系統(tǒng) API 中“正常工作”。ghN28資訊網(wǎng)——每日最新資訊28at.com

使用 fsx 檢測文件

要確定一個文件是否存在,使用 fsx.isFile(filePath) 方法,如果給定的文件存在,則返回 true ,否則返回 false 。ghN28資訊網(wǎng)——每日最新資訊28at.com

if (await fsx.isFile("/path/to/file.txt")) {  // handle the file}

與 fs.stat() 不同,如果文件不存在,這個方法會返回 false ,而不是拋出錯誤。ghN28資訊網(wǎng)——每日最新資訊28at.com

try {  const stat = await fs.stat(filePath);  return stat.isFile();} catch (ex) {  if (ex.code === "ENOENT") {    return false;  }  throw ex;}

刪除文件和目錄

fsx.delete() 方法接受一個參數(shù),即要刪除的路徑,并且對文件和目錄都有效。ghN28資訊網(wǎng)——每日最新資訊28at.com

// delete a fileawait fsx.delete("/path/to/file.txt");// delete a directoryawait fsx.delete("/path/to");

fsx.delete() 方法故意過于激進(jìn):它會遞歸地刪除目錄,即使它們不是空的(實(shí)際上是 rmdir -r)。ghN28資訊網(wǎng)——每日最新資訊28at.com

fsx 日志

fsx 的一個關(guān)鍵特性是,由于其內(nèi)置的日志系統(tǒng),很容易確定哪些方法被調(diào)用,并使用了哪些參數(shù)。要啟用 fsx 實(shí)例的日志記錄,請調(diào)用 logStart() 方法并傳入一個日志名稱。當(dāng)你完成日志記錄時,請調(diào)用 logEnd() 并傳入相同的名稱來檢索日志條目的數(shù)組。ghN28資訊網(wǎng)——每日最新資訊28at.com

fsx.logStart("test1");const fileFound = await fsx.isFile("/path/to/file.txt");const logs = fsx.logEnd("test1");

每個日志條目都是一個包含以下屬性的對象:ghN28資訊網(wǎng)——每日最新資訊28at.com

  • timestamp - 創(chuàng)建日志的數(shù)字時間戳
  • type - 描述日志類型的字符串
  • data - 與日志相關(guān)的附加數(shù)據(jù)

對于方法調(diào)用,日志條目的 type 是 call ,而 data 屬性是一個對象,包含:ghN28資訊網(wǎng)——每日最新資訊28at.com

  • methodName - 被調(diào)用的方法的名稱
  • args - 傳遞給方法的參數(shù)數(shù)組。

對于前面的例子, logs 將包含一個條目:ghN28資訊網(wǎng)——每日最新資訊28at.com

// example log entry{    timestamp: 123456789,    type: "call",    data: {        methodName: "isFile",        args: ["/path/to/file.txt"]    }}

了解這一點(diǎn)后,您可以輕松地在測試中設(shè)置日志記錄,然后檢查調(diào)用了哪些方法,而無需使用第三方間諜庫。ghN28資訊網(wǎng)——每日最新資訊28at.com

使用 fsx impls

fsx 的設(shè)計(jì)是這樣的,抽象的核心功能包含在 fsx-core 包中,每個運(yùn)行時包都擴(kuò)展了該功能,使用特定于運(yùn)行時的文件系統(tǒng)操作實(shí)現(xiàn),這些操作被包裝在一個稱為 impl 的對象中。ghN28資訊網(wǎng)——每日最新資訊28at.com

  1. fsx 單例
  2. 一個構(gòu)造函數(shù),可以創(chuàng)建 fsx 的另一個實(shí)例(比如 fsx-node 中的 NodeFsx )
  3. 一個構(gòu)造函數(shù),可以創(chuàng)建運(yùn)行時包的 impl 實(shí)例(如 node-fsx 中的 NodeFsxImpl )。

這可以讓您只使用所需的功能。ghN28資訊網(wǎng)——每日最新資訊28at.com

fsx 中的 base impls 和 active impls

每個 fsx 實(shí)例都有一個 base 類實(shí)現(xiàn),它定義了 fsx 對象在生產(chǎn)環(huán)境中的行為。active impls 是在任何給定時間使用的實(shí)現(xiàn),它可能也是 base 類實(shí)現(xiàn),也可能不是。你可以調(diào)用 fsx.setImpl()來改變 active impls。ghN28資訊網(wǎng)——每日最新資訊28at.com

import { fsx } from "fsx-node";fsx.setImpl({  json() {    throw Error("This operation is not supported");  },});// somewhere elseawait fsx.json("/path/to/file.json"); // throws error

在此示例中,基本實(shí)現(xiàn)被替換為自定義實(shí)現(xiàn),該自定義實(shí)現(xiàn)在調(diào)用 fsx.json() 方法時會引發(fā)錯誤。這使得您可以輕松地模擬測試方法,而不必?fù)?dān)心它可能如何影響整個包含的 fsx 對象。ghN28資訊網(wǎng)——每日最新資訊28at.com

交換 impls 進(jìn)行測試

假設(shè)你有一個名為 readConfigFile() 的函數(shù),它使用了來自 node-fsx 的 fsx 單例來讀取名為 config.json 的文件,當(dāng)測試這個函數(shù)時,你不想讓它實(shí)際訪問文件系統(tǒng),你可以把 fsx 的實(shí)現(xiàn)換成 fsx-memory 提供的內(nèi)存文件系統(tǒng)實(shí)現(xiàn),如下:ghN28資訊網(wǎng)——每日最新資訊28at.com

import { fsx } from "fsx-node";import { MemoryFsxImpl } from "fsx-memory";import { readConfigFile } from "../src/example.js";import assert from "node:assert";describe("readConfigFile()", () => {    beforeEach(() => {        fsx.setImpl(new MemoryFsxImpl());    });    afterEach(() => {        fsx.resetImpl();    });    it("should read config file", async () => {        await fsx.write("config.json", JSON.stringify({ found: true });        const result = await readConfigFile();        assert.isTrue(result.found);    });});

這就是使用 fsx 在內(nèi)存中模擬整個文件系統(tǒng)是多么容易。您不必像模塊加載器攔截那樣擔(dān)心導(dǎo)入所有測試模塊的順序,也不需要經(jīng)歷包含模擬庫的過程以確保一切正常。您只需更換測試的 impl,然后再重置它。通過這種方式,您可以以更高性能且不易出錯的方式測試文件系統(tǒng)操作。ghN28資訊網(wǎng)——每日最新資訊28at.com

命名注意事項(xiàng)

不幸的是,在我發(fā)布 fsx 的時候,亞馬遜發(fā)布了一款名為 FSx[2] 的產(chǎn)品。如果它獲得任何支持,我可能會重命名這個庫,歡迎提出建議。ghN28資訊網(wǎng)——每日最新資訊28at.com

希望得到結(jié)論和反饋

長期以來,我們一直在使用 JavaScript 運(yùn)行時中笨拙的低級文件系統(tǒng) API。fsx 庫是我嘗試重新想象現(xiàn)代文件系統(tǒng) API 的樣子,如果我們花一些時間關(guān)注最常見的情況,并改進(jìn) JavaScript 語言目前提供的人體工學(xué)設(shè)計(jì)。通過從頭開始重新思考,我認(rèn)為 fsx 為我們提供了一種更愉快的文件系統(tǒng)體驗(yàn)。ghN28資訊網(wǎng)——每日最新資訊28at.com

基礎(chǔ)庫只關(guān)注我最常用的方法,但我計(jì)劃在了解和思考用例后添加更多方法。您今天就可以試用,歡迎反饋。我很想知道你的想法!ghN28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-66538-0.htmlfsx 簡介:適用于 JavaScript 的現(xiàn)代文件系統(tǒng) API

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: AI 跟誰嘮跟誰嘮,順網(wǎng)嘮嘮打造 AI 趣味新體驗(yàn)!

下一篇: 實(shí)戰(zhàn)Arthas:常見命令與優(yōu)秀實(shí)踐

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美不卡在线| 一本色道久久综合精品竹菊| 国产精品自在线| 国产欧美一区二区精品性色| 国产亚洲综合性久久久影院| 亚洲丰满在线| 一区二区三区成人精品| 欧美一区二区日韩| 美女成人午夜| 欧美日韩在线电影| 国产日韩精品久久| 91久久午夜| 亚洲欧美日韩在线综合| 老鸭窝亚洲一区二区三区| 欧美日韩视频在线一区二区 | 欧美国产精品久久| 欧美午夜精品久久久久久孕妇| 国产色产综合色产在线视频| 在线观看一区二区精品视频| 一区二区久久| 久久久精品网| 欧美日韩免费观看一区二区三区| 国产农村妇女精品一二区| 亚洲黄一区二区| 亚洲在线视频观看| 美女精品在线| 国产精品久久久久久久久久三级| 樱花yy私人影院亚洲| 亚洲视频免费在线| 免费人成精品欧美精品| 国产精品一级| 亚洲精品久久视频| 欧美在线播放视频| 欧美日韩一区二区在线 | 亚洲精品久久久久| 久久www免费人成看片高清| 欧美日韩免费一区二区三区视频| 国内一区二区在线视频观看| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 亚洲欧美在线播放| 欧美1区视频| 国产一区二区三区丝袜| 亚洲国产小视频| 欧美一区二区三区另类| 欧美母乳在线| 精品91在线| 欧美亚洲三级| 国产精品va在线| 在线日韩精品视频| 欧美在线播放一区| 国产精品免费一区豆花| 日韩亚洲国产精品| 欧美顶级少妇做爰| 在线观看一区二区视频| 欧美在线资源| 国产精品一区二区在线观看网站 | 99av国产精品欲麻豆| 久久综合伊人77777蜜臀| 国产美女在线精品免费观看| 9色国产精品| 欧美激情综合色综合啪啪| 禁断一区二区三区在线| 欧美在线一区二区| 国产精品欧美日韩| 亚洲无吗在线| 欧美视频在线观看一区| 99视频精品在线| 欧美激情一区二区三区成人| 亚洲第一中文字幕在线观看| 久久女同互慰一区二区三区| 国产一区白浆| 欧美伊人影院| 国产精品一区二区久久久久| 亚洲一区二区三区中文字幕在线 | 午夜精品久久久久久久99樱桃 | 一区二区三区在线免费播放| 一区二区三区在线看| 久久电影一区| 国产欧美精品在线播放| 亚洲欧美影院| 国产精品专区h在线观看| 亚洲欧美国产日韩天堂区| 国产精品成人播放| 亚洲一区精品在线| 国产精品婷婷| 亚洲综合视频1区| 国产精品一区久久| 欧美一区=区| 国产一区二区丝袜高跟鞋图片| 欧美一区二区大片| 国产亚洲欧美中文| 久久精品日产第一区二区三区| 国产一区二区0| 久久一区二区三区四区| 亚洲国产黄色片| 欧美韩国在线| 国产一区av在线| 久久国产99| 精品成人在线视频| 免费黄网站欧美| 亚洲精品日韩在线观看| 欧美日韩免费高清| 亚洲欧美日韩精品久久亚洲区| 国产欧美精品一区aⅴ影院| 久久久精品999| 亚洲精品四区| 欧美天天影院| 久久国产黑丝| 亚洲福利视频免费观看| 久久aⅴ国产紧身牛仔裤| 影音先锋亚洲电影| 欧美精品久久一区| 亚洲四色影视在线观看| 国产欧美丝祙| 久色成人在线| 99re视频这里只有精品| 国产精品美女一区二区在线观看| 欧美在线二区| 91久久国产综合久久| 国产精品jizz在线观看美国| 久久国内精品视频| 亚洲人成在线播放| 国产精品久久久久久影视 | 国产精品盗摄久久久| 久久se精品一区二区| 亚洲国产岛国毛片在线| 欧美涩涩视频| 欧美专区在线观看| 亚洲国产电影| 国产精品久久| 久久男女视频| 一区二区三区精品| 国内免费精品永久在线视频| 欧美精品在线播放| 欧美一区二区三区婷婷月色| 亚洲第一主播视频| 国产精品九色蝌蚪自拍| 久久亚洲春色中文字幕久久久| 亚洲毛片网站| 国产综合在线视频| 欧美日本在线| 久久久91精品国产| 9色精品在线| 韩国久久久久| 欧美午夜精品久久久久久孕妇| 久久免费精品日本久久中文字幕| 亚洲伦理久久| 一色屋精品视频在线观看网站 | 91久久精品国产| 国产婷婷色一区二区三区| 欧美片第一页| 久久亚洲综合网| 亚洲欧美国产另类| 亚洲免费不卡| 一区二区在线免费观看| 国产精品永久| 欧美美女操人视频| 久久九九免费| 亚洲女人天堂成人av在线| 亚洲激情偷拍| 国内在线观看一区二区三区| 欧美视频在线观看 亚洲欧| 免费观看成人www动漫视频| 午夜精品理论片| 一本色道久久综合一区| 亚洲国产精品v| 国产一区清纯| 国产精品电影网站| 欧美成年人视频网站| 久久久精品午夜少妇| 亚洲女爱视频在线| 夜夜精品视频| 在线不卡中文字幕播放| 国产精品一区二区欧美| 欧美日韩一区二区免费在线观看| 毛片一区二区三区| 久久福利一区| 欧美一激情一区二区三区| 亚洲视频在线观看视频| 亚洲精品久久久久久久久久久久久| 国内外成人免费激情在线视频网站| 国产精品美女久久久浪潮软件 | 亚洲欧美中文在线视频| 一区二区不卡在线视频 午夜欧美不卡'| 悠悠资源网久久精品| 国产精品专区一| 国产精品国产三级国产专播精品人| 美女成人午夜| 久久在线播放| 久久男女视频| 久久嫩草精品久久久精品| 久久精品国产清自在天天线| 午夜精品美女自拍福到在线 | 欧美日韩亚洲一区二区三区四区 | 亚洲女人小视频在线观看| 亚洲影院在线观看| 亚洲午夜女主播在线直播| 亚洲少妇在线| 亚洲夜晚福利在线观看| 亚洲视频中文| 亚洲一区久久| 午夜精品剧场| 久久精品毛片| 久久亚洲欧美|