摘要:避免使用最低公分母方法你可能想讓你的程序像最低公分母文件系統一樣,通過將所有文件名規范化為大寫,將所有文件名規范化為格式,并將所有文件時間戳標準化為秒分辨率,這是最小公分母的方法。
使用不同的文件系統
Node公開了文件系統的許多功能,但并非所有文件系統都相似,以下是建議的最佳實踐,以便在使用不同的文件系統時保持代碼簡單和安全。
文件系統行為在使用文件系統之前,你需要知道它的行為方式,不同的文件系統表現不同,并且具有比其他或多或少的功能:區分大小寫、不區分大小寫、大小寫保留、Unicode形式保留、時間戳解析、擴展屬性、inode、Unix權限、備用數據流等。
警惕從process.platform推斷文件系統行為,例如,不要假設因為你的程序在Darwin上運行,因此你正在處理不區分大小寫的文件系統(HFS+),因為用戶可能正在使用區分大小寫的文件系統(HFSX)。類似地,不要假設因為你的程序在Linux上運行,因此你正在處理支持Unix權限和inode的文件系統,因為你可能位于特定的外部驅動器、USB或網絡驅動器上。
操作系統可能不容易推斷文件系統行為,但并不會丟失所有內容,你可以探測文件系統以查看它的實際行為,而不是保留每個已知文件系統和行為的列表(總是不完整),某些易于探測的特征的存在或缺失,往往足以推斷其他更難探測的特征的行為。
請記住,某些用戶可能在工作樹中的各種路徑上安裝了不同的文件系統。
避免使用最低公分母方法你可能想讓你的程序像最低公分母文件系統一樣,通過將所有文件名規范化為大寫,將所有文件名規范化為NFC Unicode格式,并將所有文件時間戳標準化為1秒分辨率,這是最小公分母的方法。
不要這樣做,你只能安全地與文件系統進行交互,該文件系統在各個方面具有完全相同的最小公分母特征,你將無法以用戶期望的方式使用更高級的文件系統,并且你將遇到文件名或時間戳沖突,你肯定會通過一系列復雜的相關事件來丟失和損壞用戶數據,并且你將創建即使不是不可能解決也很困難的bug。
當你以后需要支持僅具有2秒或24小時時間戳分辨率的文件系統時會發生什么?當Unicode標準進展到包括稍微不同的規范化算法時(如過去發生的那樣)會發生什么?
最小公分母方法傾向于嘗試僅使用“可移植”系統調用來創建可移植程序,這會導致程序出現漏洞,而且實際上是不可移植的。
采用超集方法通過采用超集方法充分利用你支持的每個平臺,例如,一個可移植備份程序應該在Windows系統之間正確地同步btimes(文件或文件夾的創建時間),并且不應該銷毀或更改btimes,即使Linux系統不支持btimes。相同的可移植備份程序應該在Linux系統之間正確同步Unix權限,并且不應該銷毀或更改Unix權限,即使在Windows系統上不支持Unix權限。
通過使程序像更高級的文件系統一樣處理不同的文件系統,支持所有可能功能的超集:大小寫敏感、大小寫保留、Unicode形式敏感、Unicode形式保留、Unix權限、高分辨率納秒時間戳、擴展屬性等。
在程序中保留大小寫后,如果需要與不區分大小寫的文件系統進行交互,則可以始終實現大小寫不敏感。但是,如果你放棄了程序中的大小寫保留,你就無法安全地與保留大小寫的文件系統進行交互,對于Unicode形式保留和時間戳分辨率保留也是如此。
如果文件系統為你提供小寫和大寫混合的文件名,則將文件名保留在給定的確切大小寫中,如果文件系統為你提供混合Unicode格式或NFC或NFD(或NFKC或NFKD)的文件名,則將文件名保留在給定的確切字節序列中,如果文件系統為你提供毫秒時間戳,則保持時間戳以毫秒為單位。
當你使用較小的文件系統時,你可以始終適當地進行下采樣,使用運行程序的文件系統的行為所需的比較函數。如果你知道文件系統不支持Unix權限,那么你不應該期望讀取你編寫的相同Unix權限。如果你知道文件系統不保留大小寫,那么你應該準備在程序創建abc時在目錄列表中看到ABC。但是,如果你知道文件系統確實保留了大小寫,那么在檢測文件重命名或文件系統區分大小寫時,你應該將ABC視為與abc不同的文件名。
大小寫保留你可以創建一個名為test/abc的目錄,有時會驚奇地發現fs.readdir("test")返回["ABC"],這不是Node中的bug,Node返回文件系統存儲它的文件名,并非所有文件系統都支持大小寫保留,某些文件系統將所有文件名轉換為大寫(或小寫)。
Unicode形式保留大小寫保留和Unicode形式保留是類似的概念,要理解為什么應該保留Unicode形式,請確保首先理解為什么要保留大小寫,如果正確理解,Unicode形式保留就一樣簡單。
Unicode可以使用幾個不同的字節序列對相同的字符進行編碼,幾個字符串可能看起來相同,但具有不同的字節序列。使用UTF-8字符串時,請注意你的期望與Unicode的工作方式一致。正如你不希望所有UTF-8字符編碼為單個字節一樣,你不應期望幾個在人眼看起來相同的UTF-8字符串具有相同的字節表示,這可能是你可以擁有ASCII而不是UTF-8的期望。
你可以創建一個名為test/café的目錄(NFC Unicode形式,字節序列<63 61 66 c3 a9>并且string.length === 5)并且有時你會驚訝地發現fs.readdir("test")返回["café"](NFD Unicode形式,字節序列<63 61 66 65 cc 81>并且string.length === 6),這不是Node中的bug。Node返回文件系統存儲時的文件名,并非所有文件系統都支持Unicode形式保留。
例如,HFS+會將所有文件名規范化為幾乎總是與NFD形式相同的形式,不要指望HFS+的行為與NTFS或EXT4相同,反之亦然。不要試圖通過規范化永久地更改數據作為掩蓋文件系統之間Unicode差異的漏洞抽象,這會產生問題而不解決任何問題,相反,保留Unicode形似并僅使用規范化作為比較函數。
Unicode形式不敏感Unicode形式不敏感和Unicode形式保留是兩種不同的文件系統行為,經常互相誤解。正如在存儲和傳輸文件名時將文件名永久規范化為大寫一樣,有時不正確地實現了大小寫不敏感,因此,在存儲和傳輸文件名時,通過將文件名永久規范化為某種Unicode格式(在HFS+的情況下為NFD),有時會錯誤地實現Unicode格式不敏感性。通過使用Unicode規范化進行比較,可以并且更好地實現Unicode形式不敏感而不犧牲Unicode形式保留。
比較不同的Unicode形式Node提供string.normalize("NFC" / "NFD"),你可以使用它將UTF-8字符串規范化為NFC或NFD,你永遠不應該存儲此函數的輸出,而只是將其用作比較函數的一部分,以測試兩個UTF-8字符串對于用戶是否看起來相同。
你可以使用string1.normalize("NFC") === string2.normalize("NFC")或string1.normalize("NFD") === string2.normalize("NFD")作為比較函數,你使用哪種形式并不重要。
規范化很快但你可能希望使用緩存作為比較函數的輸入,以避免多次規范化相同的字符串,如果該字符串不在緩存中,則對其進行規范化并對其進行緩存,注意不要存儲或保留緩存,只能將其用作緩存。
請注意,使用normalize()要求你的Node版本包含ICU(否則normalize()將返回原始字符串),如果你從網站下載最新版本的Node,那么它將包括ICU。
時間戳分辨率你可以將文件的mtime(修改時間)設置為1444291759414(毫秒分辨率),并有時驚訝地發現fs.stat將新mtime返回為1444291759000(1秒分辨率)或1444291758000(2秒分辨率),這不是Node中的bug。Node返回文件系統存儲它的時間戳,并非所有文件系統都支持納秒、毫秒或1秒時間戳分辨率。有些文件系統甚至對atime時間戳的分辨率非常粗糙,例如,對于一些FAT文件系統,分辨率為24小時。
不要通過規范化來破壞文件名和時間戳文件名和時間戳是用戶數據,正如你永遠不會自動重寫用戶文件數據以使數據大寫或將CRLF規范化為LF行結束一樣,因此你不應該通過大小寫/Unicode格式/時間戳規范化來更改、干擾或損壞文件名或時間戳,規范化只應用于比較,絕不能用于改變數據。
規范化實際上是有損哈希碼,你可以使用它來測試某些類型的等價性(例如,即使它們具有不同的字節序列,幾個字符串看起來相同)但你永遠不能將它用作實際數據的替代品,你的程序應按原樣傳遞文件名和時間戳數據。
你的程序可以在NFC中創建新數據(或者以其喜歡的任何Unicode形式組合)或使用小寫或大寫文件名,或者使用2秒的分辨率時間戳,但是你的程序不應該通過強加大小寫/Unicode形式/時間戳規范化來破壞現有的用戶數據。相反,采用超集方法并在程序中保留大小寫、Unicode格式和時間戳分辨率,這樣,你就可以安全地與執行相同操作的文件系統進行交互。
適當地使用標準化比較功能確保正確使用大小寫/Unicode形式/時間戳比較功能,如果你正在處理區分大小寫的文件系統,請不要使用不區分大小寫的文件名比較函數。如果你正在使用Unicode形式敏感文件系統(例如NTFS和大多數保留NFC和NFD或混合Unicode形式的Linux文件系統),請不要使用Unicode形式不敏感的比較函數。如果你正在使用納秒時間戳分辨率文件系統,請不要以2秒分辨率比較時間戳。
為比較功能的微小差異做好準備請注意你的比較函數與文件系統的比較函數匹配(或者如果可能的話探測文件系統以查看它實際比較的方式),例如,不區分大小寫比簡單的toLowerCase()比較復雜,事實上,toUpperCase()通常比toLowerCase()更好(因為它以不同的方式處理某些外語字符)。但更好的方法是探測文件系統,因為每個文件系統都有自己的大小寫比較表。
例如,Apple的HFS+將文件名規范化為NFD格式,但這種NFD格式實際上是當前NFD格式的舊版本,有時可能與最新的Unicode標準的NFD格式略有不同,不要指望HFS+ NFD始終與Unicode NFD完全相同。
上一篇:HTTP事務的剖析 下一篇:流中的背壓文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100319.html
摘要:確保兼容性的剩余責任在于團隊維護頭文件,這些頭文件提供了在編譯時在中保持穩定的。中的穩定性提供由幾個獨立團隊維護的頭文件,例如,團隊維護諸如和之類的頭文件。由團隊維護,盡管與團隊密切合作,但該團隊是獨立的,并且有自己的時間表和優先級。 ABI穩定性 介紹 應用程序二進制接口(ABI)是程序調用函數和使用其他編譯程序的數據結構的一種方法,它是應用程序編程接口(API)的編譯版本,換句話說...
摘要:在數據緩沖區已超過或寫入隊列當前正忙的任何情況下,將返回。當返回值時,背壓系統啟動,它會暫停傳入的流發送任何數據,并等待消費者再次準備就緒,清空數據緩沖區后,將發出事件并恢復傳入的數據流。 流中的背壓 在數據處理過程中會出現一個叫做背壓的常見問題,它描述了數據傳輸過程中緩沖區后面數據的累積,當傳輸的接收端具有復雜的操作時,或者由于某種原因速度較慢時,來自傳入源的數據就有累積的趨勢,就像...
摘要:將如下代碼寫入到文件中,并在環境里執行如圖雖然這兩個輸出看起來可能一樣,但系統實際上對它的處理方式有不同。如圖如果你沒有啟動調試日志,則不會看到任何這樣的日志輸出。 原文地址: https://www.twilio.com/blog/g...原文作者: DOMINIK KUNDEL 翻譯作者: icepy 翻譯出處: https://github.com/lightningm... ...
摘要:定時器在和瀏覽器中的表現形式是相同的。關于定時器的一個重要的事情是,我們提供的延遲不代表在這個時間之后回調就會被執行。它的真正含義是,一旦主線程完成所有操作包括微任務并且沒有其它具有更高優先級的定時器,將在此時間之后執行回調。 眾成翻譯 原文鏈接 關于作者 2018年6月21日出版? 本指南面向了解Javascript但尚未十分熟悉Node.js的前端開發人員。我這里不專注于語言本身...
摘要:快速入門提供了豐富的本地操作系統的,使你能夠使用純來創建桌面應用程序。這并不意味著是一個綁定圖形用戶界面的庫。每個頁面在里是運行在自己的進程里,這些進程被稱為渲染進程。有些只能在該事件發生后才能被使用。 快速入門 Electron提供了豐富的本地(操作系統)的API,使你能夠使用純JavaScript來創建桌面應用程序。與其它各種的Node.js運行時不同的是Electron專注于桌面...
閱讀 3258·2021-11-15 11:37
閱讀 1065·2021-11-02 14:45
閱讀 3893·2021-09-04 16:48
閱讀 3569·2019-08-30 15:55
閱讀 748·2019-08-23 17:53
閱讀 994·2019-08-23 17:03
閱讀 2020·2019-08-23 16:43
閱讀 2182·2019-08-23 16:22