虛擬文件系統(VFS)是一個抽象概念,它具有極其高效的用途。幾種流行的語言現在都支持 VFS 構造,Cameron Laird 向您說明這些構造適用於什麼。 “不親自嘗試就不會明白它是多麼有用”。當有人對我這麼說時,我一貫的反應就是認為說這話的人對所說的功能不夠
虛擬文件系統(VFS)是一個抽象概念,它具有極其高效的用途。幾種流行的語言現在都支持 VFS 構造,Cameron Laird 向您說明這些構造適用於什麼。
“不親自嘗試就不會明白它是多麼有用”。當有人對我這麼說時,我一貫的反應就是認為說這話的人對所說的功能不夠了解,所以沒法說清楚。
但是,對於虛擬文件系統,親身經歷告訴我說這話的人是對的。 Jeffrey Hobbs 是 ActiveState Corp. 的高開發人員,我們倆都見識了使用虛擬文件系統(VFS)可以實現多麼不可思議的強大功能。
簡單的構想,重大的成果 VFS 背後的構想很簡單:它將不是文件系統的事物表示為文件系統。這裡的文件系統指的是“傳統的類 Linux 文件系統”:由可直接訪問的目錄和(普通)文件構成的樹或層次結構。當然,這個概念會激起所有 Linux 用戶的興趣,因為 Linux 本身的許多特征都源自 UNIX 文件系統內對設備、表和其它對象的表示。UNIX 建立在如下原則之上:每樣東西(或者至少是許多東西)都是文件;VFS 將這一原則加以推廣,將盡可能多的東西看成是文件系統。
注:Linux 內核工程師也談到了 VFS,但意義不同。本月的專欄文章不是關於 Linux 虛擬文件系統交換器的,該交換器將文件系統驅動程序分派給 ext2、ext3、reiserfs 等等。
對 VFS 的一種看法是:它是某種技術或概念的另一個示例,用獨立開發人員 Jean-Claude Wippler 的話說,這種技術“使 OS 和高級語言環境之間的界限變得模糊”。另外,“系統服務”在應用程序
開發語言中的出現使可移植性變得更為容易,因為操作系統從視野中消失。
那麼,哪類東西本身不是文件系統,但用這種方式表示卻非常有用呢?這有許多:可以通過 FTP、HTTP、WebDAV 或其它網絡協議訪問的文件;.zip 文件、
CVS(並發
版本控制系統,concurrent versions system)或其它歸檔文件的內容;
數據庫表;受
安全性或其它約束限制的真正文件系統的投影(projection);及其它。
容易看出這樣的資源可以以自然的方式映射到文件系統。假定 example.zip 壓縮了下面這些文件:
first
subdir1/second
subdir1/third
subdir2/fourth
該歸檔文件很可能創建為現有文件系統樹的直接(局部)映像,所以自然可以用有根樹表示:
./first
./subdir1/second
./subdir1/third
./subdir2/fourth
許多在業界有影響的產品都依賴於 VFS。象日志記錄文件系統這樣的 DB2 功能部件的體系結構就依靠於 VFS 模型。眾所周知的 Zope 應用程序
服務器提供了一個頗有挑戰性的 VFS 示例。Zope 的“獲得(a
cquisition)”概念將程序化的對象映射成 URL。在 Zope 中,類似於下面這樣的方法調用:
context.myproject.object1.method1(year = "1999")
相當於對下面這個 URL 的 HTTP 請求:
http://myzope.com/myproject/object1/method1?year=1999
看出其中的優點了嗎?VFS 和 UNIX 的“一切均是文件”的概念也很相似,因為這個想法很容易理解和模仿,但是要意識到它能將應用程序設計簡化到哪種程度,還需要花幾年工夫。
我們來研究一個示例。假定您已經編寫了一個文本編輯器;它提供了訪問、讀取、修改單獨文件以及將它們寫回到存儲器的方法。如果使用文件系統“虛擬器”,立刻就可以使用所有相同的代碼來浏覽 FTP 或 ZIP 歸檔文件,選擇、修改並保存單獨的項。您擁有在操作本地文件時能很好地工作的浏覽器、備份實用程序、安全性掃描程序或版本控制系統嗎?對其文件系統訪問進行虛擬化,它立刻就可以對 .tar 文件、老式磁帶盤和只能通過虛擬專用網(VPN)訪問的公司資源進行操作。供應商喜歡把這樣的附件賣到數千美元。VFS 卻免費提供了這樣的功能。
或者說這幾乎是免費的。
程序員不用學習任何新
知識;他們只需要像以往那樣執行相同的 open、close 等文件系統操作。關鍵是所有的代碼都和以前的一樣。最大的困難就是當前支持成熟的 VFS 的語言運行時庫很少。常見的困難之一是驅動程序通常是只讀的,這或者是因為寫功能需要進行更為復雜的編程,或者只是因為在類似 HTTP 這樣的協議中沒有定義寫操作。
哪種語言具有 VFS 功能? 對 VFS 支持得最好的語言是 Tcl,ActiveState 的 Hobbs 擅長於這種語言。在其它語言(包括 Java 和 Perl)中,現有的 VFS 實現是“不純的”,因為它們在實現中提供了新方法(比如 Perl 的 vfsopen)來補充核心庫入口點。相比之下,在 Tcl 的發行版 8.4 中,正如有關 VFS 的社區頁面所說明的那樣:“Tcl 的文件系統是完全支持虛擬文件系統的”。尤其重要的是,這意味著在任何識別普通文件的地方,可以按語法規則使用虛擬文件資源。典型的 Tcl 允許:
image create -file myimage.gif
Tcl 8.4 將這一用法自然地擴展成:
image create -file ftp://myserver.com/myimage.gif
獨立顧問 Matt Newman 首先在 20 世紀 90 年代末為 Tcl 實現了健壯的 VFS,以幫助他為某個大型
金融企業所做的開發工作。在 2000 年底,Eurob
ios 科學家 Vince Darley 准備雄心勃勃地重新編寫 Tcl 的文件系統應用程序編程接口(API),其中的優點之一就是提供 VFS 掛鉤(hook)。
大多數在職的 Tcl 應用程序開發人員首先將 VFS 應用在上述的示例方面 - 例如靈活的支持 FTP 的編輯器。但值得注意的是,Tcl 的 VFS 先驅者(包括 Wippler,在前一篇有關應用程序部署的“服務器診所(Server clinic)”專欄文章中曾提到過,請參閱參考資料)的初衷是開發“徹底的”VFS。也就是,不是使用 VFS 技術去訪問現有的外部資源,而是要將一個特殊用途的數據庫(位於應用程序內部)當作一個完整的文件系統進行管理。他們已經通過該機制顯著地簡化了應用程序開發和部署。從這個角度看,VFS 可以用來統一和整合不同的操作環境 - 開發、質保、客戶站點,這樣應用程序可以在所有操作環境中一致地操作。透明地將文件系統推廣到外部文件,這只是附帶的好處。清單 1 顯示了兩個摘自 Tcl 社區頁面的代碼示例,它們暗示了這個附帶的好處的強大功能。
清單 1. 在 Tcl 中使用 VFS
package require vfs::urltype
vfs::urltype::Mount ftp
# With VFS activated, normal Tcl file commands
# can copy files even to and from FTP servers.
file copy ftp://foo.bar.com/pub/Readme .
file copy myfile ftp://user:
[email protected]/private.txt
package require vfs::zip
vfs::zip::Mount foo.zip foo.zip
# foo.zip is now part of the normal filesystem hierarchy.
cd foo.zip
# Within subdir1 on foo.zip, list all items.
set listing [glob -dir subdir1 *]
大多數語言都有訪問 FTP 或 ZIP 的工具。從這個意義上說,VFS 類似於
面向對象的高級語言或運行時庫:它不提供任何新內容,您可以自己編程來做 VFS 可以做的任何事。但是,有了 VFS,資源管理就變得非常容易且更加合理。它不是個很難的概念;只是個很好的概念。
VFS 簡化了許多有趣的問題。Tcl 程序員目前正在處理類似於下面這樣的問題:
版本化的可動態裝入庫的集中壓縮歸檔文件
智能網絡代理程序
高級的“混合介質”備份管理器
我已經試驗過“活動系統文件”的可編程性。可以把它們看作某些語言所支持的“特性”。特性是其訪問會包括寫操作副作用的屬性:
result = thing.property
可能不只是從內存檢索“property”的值,而有可能涉及這樣的計算:在網絡上傳送數據、檢查系統狀態,等等。類似地,當我寫:
file copy report.pdf backup
這不僅僅是將文件復制到目錄中,而是要根據環境生成文件並執行其它操作。
面向特性的編程因其副作用較多,而被認為是“危險”的,基本上,用顯式存取方法不能完成的操作,它也肯定完成不了。然而,它這種樣式仍適合某些情形,而且我發現活動文件系統至少有時候要比它們所替代的 makefile 和腳本更容易編碼。
結束語 Tcl 在其 VFS 成熟性方面要領先於其它語言;它已經解決了字符編碼、I/O 體系結構和
性能約束方面的難題,這些難題在其它語言社區中現在才剛開始顯現。但是,您不一定非要使用 Tcl 才能應用 VFS 的思想。您自己的編程能從更為一致的訪問類文件資源的方式中獲益嗎?大多數現代語言都提供了某種擴展內置構造的方法,因此可以用更一致和功能更強大的方式來編碼 I/O。