Java之IO(五)檔案系統

來源:互聯網
上載者:User

標籤:nat   比較   except   down   允許   額外   created   時間戳記   readonly   

  轉載請註明源出處:http://www.cnblogs.com/lighten/p/6992043.html

1.前言

  在講解Java的檔案流之前,先來認識一下Java的檔案系統的實現。值得一提的是,Java8與Java7相比,對這一塊做了一些改動,接下來會進行對比介紹,但主要還是以Java8為主。

1.1 Java7與Java8不同之處概覽

  首先,Java8多了一個DefaultFileSystem,但少了一個Win32FileSystem類,其次兩者的抽象父類FileSystem有些許區別。Java7的抽象父類有一個靜態native方法,FileSystem getFileSystem();

而Java8沒有。在File類檔案我們可以看到,Java7擷取電腦主機的檔案系統就是通過FileSystem.getFileSystem();而Java8則是通過DefaultFileSystem.getFileSystem();

  這個WinNTFileSystem是兩個版本都有的一個類,但實現不一樣,由於Java7存在Win32FileSystem,其WinNTFileSystem類是繼承自Win32FileSystem,Java8沒有這個類,所以其是直接繼承抽象父類FileSystem。從這裡我們也可以看出區別了,Java7是通過native方法來選擇主機的檔案系統實作類別執行個體。但是Java8隻有WinNTFileSystem一個實作類別,沒有Win32FileSystem的,因此就是直接返回一個WinNTFileSystem執行個體。後面將比較WinNTFileSystem在兩個版本的不同之處。

2.WinNTFileSystem

  FileSystem中定義了許多的抽象方法,具體如下:

  

  涉及到檔案系統的查詢,添加刪除都是native方法,具體如下:

private native String getDriveDirectory(int drive);    //擷取磁碟目錄,A~Z盤符private native String canonicalize0(String path)            throws IOException;    // 正常化檔案路徑private native String canonicalizeWithPrefix0(String canonicalPrefix,            String pathWithCanonicalPrefix)            throws IOException;    // 這個也是正常化,不過其假定之前的路徑都是規範的,只需要規範路徑最後一個元素// 一些檔案的操作,檔案資訊的讀取,刪除建立目錄及檔案許可權等等public native int getBooleanAttributes(File f);     public native boolean checkAccess(File f, int access);public native long getLastModifiedTime(File f);public native long getLength(File f);public native boolean setPermission(File f, int access, boolean enable,            boolean owneronly);public native boolean createFileExclusively(String path)            throws IOException;public native String[] list(File f);public native boolean createDirectory(File f);public native boolean setLastModifiedTime(File f, long time);public native boolean setReadOnly(File f);private native boolean delete0(File f);private native boolean rename0(File f1, File f2);private static native int listRoots0();private native long getSpace0(File f, int t);private static native void initIDs();

  Java7與Java8針對於檔案的一些操作方法,在WinNTFileSystem大致相同,不過Java7是將其實現在Win32FileSystem類中。雖說是大致相同,但是還是有些許差別。Win32FileSystem擷取磁碟使用大小如下:

  兩個版本的WinNTFileSystem的實現卻是一樣的。

  這裡為什麼不需要相容Win32就不清楚了,或許是在使用時判斷過了,或許是native方法getSpace0的實現方法不同了。而除了這個方法,兩者的這個WinNTFileSystem都實現都是一樣的,Java7的Win32FileSystem就是一個getSpace與WinNTFileSystem,這也難怪移除了這個類,只使用WinNTFileSystem這個類了。

  由於大部分方法都是些native方法,調用這些方法的方法實現也比較簡單,這裡就不進行說明了,直接看源碼就很明白了。這裡簡單介紹一下檔案路徑的處理過程。

  1.public String canonicalize(String path);

    (1)判斷path長度:

      長度為兩位,格式是字母:,則返回大寫字母:,比如C:

      長度為三位,格式是字母:\\,則返回大寫字母:\\,如C:\\

    (2)判斷設定是否需要緩衝路徑:

      不需要,調用native方法canonicalize0

      需要,擷取緩衝cache,存在就直接返回。不存在:

      (a)如果使用緩衝的路徑首碼,通過parentOrNull擷取檔案的父路徑,沒有則為null。如果父路徑不為空白,取緩衝prefixCache,緩衝為空白,就調用canonicalizeWithPrefix,注意這裡放入的緩衝是cache,這個結果就是我們需要的整個路徑格式化結果。

      (b)如果結果還是null,就使用navtive方法的canonicalize0擷取格式化路徑。放入cache緩衝。注意,如果需要緩衝首碼,並且a步驟解析的父路徑不為空白,就重新通過格式化後的路徑擷取父檔案,存在且格式化後的路徑也是一個檔案存在且不是目錄,就將結果存入prefixCache。

  這個解析過程看過去很麻煩,為什麼不直接調用canonicalize0方法。主要是通過使用緩衝,可以改進啟動的效能。值得注意的是,a步驟和b步驟放入cache中的索引值寫法是不一樣的,但是結果是一致的,cache處理的是相同path的格式化路徑,索引值就是傳入的path,prefixCache處理的是父目錄目錄的格式化路徑,取出來的是父目錄的格式化路徑,確保與native演算法canonicalize_md.c中的結果一致,進行了相應的轉換處理,所以源碼看過去有些繁瑣。

3.File

  File類有四種構造方法:

  不管是哪種方式,最終都是要初始化兩個參數:

  下面這些檔案方式,都是使用了FileSystem的與路徑處理相關的方法:

  而剩下的所有方法,都與FileSystem的native方法相關了,沒有太多介紹的必要。唯一有點意思的就是deleteOnExit()方法,其實現與DeleteOnExitHook類相關,這個類最後會介紹。

4.其它相關類4.1 ExpiringCache

  第2節講到過擷取路徑的標準字串時使用到了緩衝,這個緩衝就是ExpiringCache類,這是一個帶時效的緩衝,實現關鍵就在於初始化的時候需要給一個逾時時間

  其儲存的不只是索引值,值是一個Entry,有額外的儲存時間欄位

  在儲存的時候會加上儲存時間戳記,擷取的時候會比較一下目前時間是否逾時。逾時就清除返回null,否則就返回所需要的值。

 4.2DeleteOnExitHook

  File類的deleteOnExit()方法就是使用了這個類。實際上開源架構dubbo的停機也使用了其中的機制。Java目前在JVM關閉的時候提供了一個鉤子(hook),這個允許你在JVM關閉的時候執行一些代碼,這個類就是在關閉的時候執行刪除需要刪除的檔案。一般是通過Runtime.getRuntime().addShutdownHook(new Thread())進行的。DeleteOnExitHook是使用了一個sun.misc.SharedSecrets類來完成的,原理應該一樣的。hook在以下情況會生效:

  1.程式運行完成退出

  2.使用System.exit()方法退出

  3.終端運行時使用ctrl+c中止程式

  4.系統關閉

  5.OutOfMemory造成宕機

  6.kill pid命令殺死進程(kill -9 pid不行)

Java之IO(五)檔案系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.