1. 程式人生 > >關於文件的INode與Java中的文件操作接口

關於文件的INode與Java中的文件操作接口

日誌文件 mic padding 獲得 有關 測試 set 錯誤 關閉

本文由作者周梁偉授權網易雲社區發布。


近日做的項目中涉及到多進程共同讀寫多個文件的問題,文件名和最後修改時間都是可能會被頻繁修改的,因而識別文件的唯一性會產生相當的麻煩,於是專門再學習了一下文件系統對文件的組織管理方式。

一、 文件在文件系統中的組織方式

一塊物理磁盤可以被分為若幹個分區,分區的初始化操作就是在上面建立文件系統,如ext3,ext4,ntfs或fat32等都是文件系統的概念,還有網絡文件系統如NFS等。同塊磁盤上的不同分區也可以被指定不同的文件系統,文件系統對文件在磁盤上的數據讀寫方式做了抽象。一個文件系統中又被分為多個卷(Cylinder Group),每個卷中最主要的部分是inode基路段和數據塊段。i-node結構唯一指定了一個文件實例,這個數據結構中包括了inode編號,所有包含的數據塊的信息和該inode被引用的計數等。可以這麽認為,要唯一識別的一個磁盤上的文件,只需要獲得inode-number就可以了。文件或者目錄則是存放在數據塊中directory block,其中包含了文件名和實體文件的inode-number等信息。文件名是可以隨時被改變的,只要其中的inode-number沒有發生改變,則指向的就是同一個文件。所以在應用程序中要判斷文件是否相同如果依靠filename是不可靠的,只有獲取到文件的inode-number才是可靠的。如在log4j這種日誌應用中,日誌文件的歸檔方式會使文件名不斷發生變化,當前你less到的app.log在下一分鐘可能就變成了app.log.1。在這種場景下,程序只能通過獲取文件inode-number來識別文件。

技術分享圖片

技術分享圖片

二、 文件操作

前面說了文件在磁盤上的存放是以inode-number為唯一id來區分的,在進程打開一個文件讀寫時,操作系統又會為文件分配一個"指針"來訪問文件,而不是直接使用inode-number。這個指針就是FileDescriptor(下面簡稱FD),FD是一個動態的概念,是進程中調用create後open文件操作是返回的一個Long值,當文件關閉時這個FD也就失效了,所以同一個文件如果被打開兩次獲取到的FD會是不同的。進程打開文件的情況如下圖所示,在進程中維護了一張表記錄所有打開的文件,每一條記錄表示一個FileDescriptor,每個進程在開始時都默認打開了三個文件,FileDescriptor分別是0,1,2,既stdin, stdout和stderr。FD記錄中包含了一張FileTable,記錄了文件的狀態信息,offset和V-node指針,V-Node指針才真正指向了磁盤上的文件實體。(這裏的V-Node是在inode之上抽象出來的概念,因為i-node在不同的文件系統中會有實現上的差異,V-Node是為了統一不同文件系統的接口抽象出來的一層,在Linux中V-Node被稱為 FileSystem independent INode ,而INode 稱為FileSystem dependent Inode,我們可以簡單的理解為 V-Node就是INode)。

技術分享圖片

當一個文件被多個進程共享讀寫時,可以看如下圖:

技術分享圖片

這裏進程A的fd3和進程B的fd4其實指向的是同一個實體文件,但是這兩個進程維護了兩張不同的文件表,維護了不同的offset位置。所以如果進程不是采用append方式寫文件,兩個進程寫入的內容可能出現相互覆蓋。這裏也可能看到雖然FD不同,但是可以指向同一個實體文件,也說明了用FD來判斷文件唯一性是不靠譜的。
關於FD和INode,還有關於緩存的重要註意事項。
由於操作系統在接收到文件寫請求時可能將寫入內容放到緩存中,所以提供了flush和sync等操作來將緩存中的內容強制刷入磁盤。但是這兩個操作作用是不同的。
flush會將數據刷入到FileDescriptor中,但是不會刷入Inode
sync/fsync/fdatasync則會強制將FD中的數據刷入Inode中。

三、 Java操作文件的接口

技術分享圖片

最後需要註意的一點是,雖然在文件的存續期間,inode可以認為是識別該文件的唯一標識,但是文件系統對inode有回收重用的機制,在文件被刪除之後,原來的inode可以被分配給新創建的文件,這種情況下,如果一味以inode相同來判定新舊文件是不是同一個文件可能會出現錯誤;應對這種情況確實也沒有更好的辦法,一種解決方法是,提取文件中部分內容的MD5或SHA-1這種指紋信息作為標識,以inode+md5是否相同來決定是否是同個文件。



免費領取驗證碼、內容安全、短信發送、直播點播體驗包及雲服務器等套餐

更多網易技術、產品、運營經驗分享請訪問網易雲社區。

相關文章:
【推薦】 初步探索前端性能測試
【推薦】 四步詳解數據分析套路
【推薦】 邏輯編程入門--clojure.core.logic

關於文件的INode與Java中的文件操作接口