[二] JavaIO之File詳解 以及FileSystem WinNTFileSystem簡介

File類
文件和目錄路徑名的抽象表示形式。
咱們知道,對於不一樣的操做系統,文件路徑的描述是不一樣的
好比
windows平臺:用\
linux平臺:用/
 
File是Java爲了這一律念提供的抽象描述,與系統無關的視圖
抽象路徑名 有兩個組件:
1.可選的與系統有關的前綴  字符串   好比盤符,"/" 表示 UNIX 中的根目錄,"\\\\" 表示 Microsoft Windows UNC 路徑名
2.零個或者多個  字符串  名稱 序列
 
第一個名稱是 目錄名,第一個名稱以後每一個名稱表示一個目錄,最後一個名稱既能夠是目錄,也能夠是名稱
空 抽象路徑名沒有前綴和名稱序列
注意:
既然最後一個名稱能夠是目錄,也能夠是文件名稱,那麼File 並不必定就是一個文件,也能夠是一個文件路徑,也就是目錄

構造方法

java中使用File來抽象表示 文件/目錄這一個概念
也就是在Java中,想要表示一個文件,構造一個File對象便可
構造方法
File(File parent, String child)
根據 parent 抽象路徑名和 child 路徑名字符串建立一個新 File 實例。
File(String pathname)
經過將給定路徑名字符串轉換爲抽象路徑名來建立一個新 File 實例。
File(String parent, String child)
根據 parent 路徑名字符串和 child 路徑名字符串建立一個新 File 實例。
File(URI uri)
經過將給定的 file: URI 轉換爲一個抽象路徑名來建立一個新的 File 實例。
 
經過路徑構造一個File,是最天然地作法
 
File(File parent, String child)根據參數file的路徑和child字符串進行組合
File(String parent, String child)根據參數 parent字符串和child字符串組合
本質上也就仍是路徑,不過很顯然,拼接 child 就能夠進行建立子目錄
 
URI是統一資源標識符,將文件轉換成一個連接,能夠網絡訪問 ,經過這個URI 也能夠用來生成文件
 
new File只是在java中描述這麼一個文件,是否真的存在? 你還須要進行去驗證,只是一個虛擬的描述符
File file = new File("D:\\testFile");//file就是對這個路徑的一個描述,那麼是否真的存在? 你還須要進行去驗證

名稱與路徑的分隔符

另外File 中還包括兩個分隔符
目錄分隔符  名稱分隔符的兩種形式  char 和 String
separatorChar
public static final char separatorChar
與系統有關的默認名稱分隔符。
此字段被初始化爲包含系統屬性 file.separator 值的第一個字符。
在 UNIX 系統上,此字段的值爲 '/';在 Microsoft Windows 系統上,它爲 '\\'。
separator
public static final String separator
與系統有關的默認名稱分隔符,爲了方便,它被表示爲一個字符串。此字符串只包含一個字符,即 separatorChar。
pathSeparatorChar
public static final char pathSeparatorChar
與系統有關的路徑分隔符。
此字段被初始爲包含系統屬性 path.separator 值的第一個字符。
此字符用於分隔以路徑列表 形式給定的文件序列中的文件名。
在 UNIX 系統上,此字段爲 ':';在  Microsoft Windows 系統上,它爲 ';'。
pathSeparator
public static final String pathSeparator
與系統有關的路徑分隔符,爲了方便,它被表示爲一個字符串。
此字符串只包含一個字符,即 pathSeparatorChar。 

File API分類

File既多是目錄,也多是文件
那麼,他必然提供了文件和目錄的一些基本常見操做
按照文件的屬性以及相關操做對API進行分類
 
文件自身屬性讀取
getName()
getParent()
getParentFile()
getPath()
isHidden()
lastModified()
length()
isAbsolute()
isDirectory()
isFile()
exists()
getAbsoluteFile()
getAbsolutePath()
getCanonicalFile()
getCanonicalPath()
getFreeSpace()
getTotalSpace()
getUsableSpace()
建立文件/目錄基本操做       
mkdir()
mkdirs()
delete()
deleteOnExit()
renameTo(File)
createTempFile(String, String)
createTempFile(String, String, File)
createNewFile()
文件/目錄 列表讀取
listRoots()
list()
list(FilenameFilter)
listFiles()
listFiles(FileFilter)
listFiles(FilenameFilter)
文件權限訪問以及文件信息設置
canExecute()
canRead()
canWrite()
 
setExecutable(boolean)
setExecutable(boolean, boolean)
setReadable(boolean)
setReadable(boolean, boolean)
setReadOnly()
setWritable(boolean)
setWritable(boolean, boolean)
setLastModified(long)
其餘
toPath()
toString()
toURI()
 
equals(Object)
compareTo(File)
hashCode()
 

File API詳解

 
測試:
image_5b9396eb_32ae

File相關的基礎信息屬性

public String getName() 返回由此抽象路徑名錶示的文件或目錄的名稱。
該名稱是路徑名名稱序列中的最後一個名稱。若是路徑名名稱序列爲空,則返回空字符串。
測試信息: getName():  cccc.txt
public String getParent() 返回此抽象路徑名父目錄的路徑名字符串;
若是此路徑名沒有指定父目錄,則返回 null。
getParent():  D:\testFile
public File getParentFile() public String getParent() 的File形式,等同於new File(getParent())
public String getPath() 將此抽象路徑名轉換爲一個路徑名字符串。
所得字符串使用  默認名稱分隔符  分隔名稱序列中的名稱。 
 
一個File用於描述一個抽象路徑名
這個抽象路徑名(File) 的名稱 name爲  路徑名名稱序列中的最後一個名稱 
這個抽象路徑名(File) 的父 parent爲  路徑名名稱序列中的除了最後一個名稱之外的全部 
這個抽象路徑名(File) 的路徑path爲  路徑名名稱序列中全部的名稱,只不過使用默認的的名稱分隔符分割
 
image_5b9396eb_1578
 
image_5b9396eb_6d68
 
public boolean isHidden() 是否隱藏文件
測試此抽象路徑名指定的文件是不是一個隱藏文件。
隱藏 的具體定義與系統有關
public long lastModified()
long 毫秒數
表示文件最後一次被修改的時間的 long 值,
用與時間點(1970 年 1 月 1 日,00:00:00 GMT)之間的毫秒數表示;
若是該文件不存在,或者發生 I/O 錯誤,則返回 0L
public long length() 長度,字節
返回由此抽象路徑名錶示的文件的長度。
若是此路徑名錶示一個目錄,則返回值是不肯定的。
此抽象路徑名錶示的文件的長度,以字節爲單位;
若是文件不存在,則返回 0L。
對於表示特定於系統的實體(好比設備或管道)的路徑名,某些操做系統可能返回 0L。
public boolean isAbsolute()
是否絕對路徑
測試此抽象路徑名是否爲絕對路徑名。絕對路徑名的定義與系統有關。
在 UNIX 系統上,若是路徑名的前綴是 "/",那麼該路徑名是絕對路徑名。
在 Microsoft Windows 系統上,
若是路徑名的前綴是後跟 "\\" 的盤符,或者是 "\\\\",那麼該路徑名是絕對路徑名。
public boolean isDirectory() 當且僅當此抽象路徑名錶示的文件存在且 是一個目錄時,返回 true;不然返回 false 
public boolean isFile() 當且僅當此抽象路徑名錶示的文件存在且 是一個標準文件時,返回 true;不然返回 false
public boolean exists() 當且僅當此抽象路徑名錶示的文件或目錄存在時,返回 true;不然返回 false 
public String getAbsolutePath() 絕對路徑名字符串,它與此抽象路徑名錶示相同的文件或目錄
public File getAbsoluteFile()
絕對    抽象路徑名,它與此抽象路徑名錶示相同的文件或目錄  至關於new File(this.getAbsolutePath())
 
 
規範路徑名是絕對路徑名,而且是唯一的。規範路徑名的準肯定義與系統有關。
若有必要,此方法首先將路徑名轉換爲絕對路徑名,這與調用 getAbsolutePath() 方法的效果同樣,而後用與系統相關的方式將它映射到其唯一路徑名。
這一般涉及到從路徑名中移除多餘的名稱(好比 "." 和 "..")、解析符號鏈接(對於 UNIX 平臺),以及將驅動器號轉換爲標準大小寫形式(對於 Microsoft Windows 平臺)。
 
每一個表示現存文件或目錄的路徑名都有一個唯一的規範形式
每一個表示不存在文件或目錄的路徑名也有一個唯一的規範形式。
不存在文件或目錄路徑名的規範形式可能不一樣於建立文件或目錄以後同一路徑名的規範形式。
一樣,現存文件或目錄路徑名的規範形式可能不一樣於刪除文件或目錄以後同一路徑名的規範形式。
 
public String getCanonicalPath()
                        throws IOException
規範路徑名字符串,它與此抽象路徑名錶示相同的文件或目錄
 
public File getCanonicalFile()
                      throws IOException
等同於 new File(this.getCanonicalPath()) 
 
 
public long getFreeSpace()
public long getTotalSpace()
public long getUsableSpace()
返回此抽象路徑名指定的分區中空間相關的數據信息,必定注意是抽象路徑名指定的分區
未分配 /所有/已使用   空間狀況
單位是字節數

File相關的操做

建立 重命名 刪除等
mkdir()
 
建立此抽象路徑名指定的目錄,當且僅當已建立目錄時,返回 true;不然返回 false
mkdirs() 建立此抽象路徑名指定的目錄,包括全部必需但不存在的父目錄。
注意,此操做失敗時也可能已經成功地建立了一部分必需的父目錄。 
 
mkdir/mkdirs  用於建立目錄
mkdir只會建立最後一個名稱爲名稱的目錄,  若是一個路徑的parent不存在,並不會建立成功
mkdirs 則會建立全部
image_5b9396eb_319e
 
public boolean renameTo(File dest) 從新命名此抽象路徑名錶示的文件。
參數爲File
此方法行爲的許多方面都是與平臺有關的:重命名操做沒法將一個文件從一個文件系統移動到另外一個文件系統,
該操做不是不可分的,若是已經存在具備目標抽象路徑名的文件,那麼該操做可能沒法得到成功。
應該始終檢查返回值,以確保重命名操做成功。
他的參數爲File 也是一個抽象路徑名 因此說不只僅就是改一下文件的最後一個名稱
他能夠把文件進行移動
image_5b9396eb_5a1c
 
public boolean delete() 刪除此抽象路徑名錶示的文件或目錄。若是此路徑名錶示一個目錄,則該目錄必須爲空才能刪除。
當且僅當成功刪除文件或目錄時,返回 true;不然返回 false 
public void deleteOnExit()
在虛擬機終止時,請求刪除此抽象路徑名錶示的文件或目錄。 
文件(或目錄)將以與註冊相反的順序刪除。
調用此方法刪除已註冊爲刪除的文件或目錄無效。
根據 Java 語言規範中的定義,只有在虛擬機正常終止時,纔會嘗試執行刪除操做。
一旦請求了刪除操做,就沒法取消該請求。因此應當心使用此方法。
 
file1 是文件  file2是目錄,可是目錄下還有文件
因此file1刪除成功  file2刪除失敗
image_5b9396eb_35ab
 
 
 
public static File createTempFile(String prefix,
                                  String suffix,
                                  File directory)
                          throws IOException
在指定目錄中建立一個新的空文件,使用給定的前綴和後綴字符串生成其名稱。
若是 directory 參數爲 null,則使用與系統有關的默認臨時文件目錄
默認臨時文件目錄由系統屬性 java.io.tmpdir 指定
public static File createTempFile(String prefix,
                                  String suffix)
                           throws IOException
在默認臨時文件目錄中建立一個空文件,使用給定前綴和後綴生成其名稱。
調用此方法等同於調用 createTempFile(prefix, suffix, null)
public boolean createNewFile()
                      throws IOException
當且僅當不存在具備此抽象路徑名指定名稱的文件時,不可分地建立一個新的空文件。
檢查文件是否存在,若不存在則建立該文件
若是指定的文件不存在併成功地建立,則返回 true;若是指定的文件已經存在,則返回 false

File相關的列表查詢

public String[] list() 返回一個字符串數組,這些字符串指定此抽象路徑名錶示的目錄中的文件和目錄。
若是此抽象路徑名不表示一個目錄,那麼此方法將返回 null。
不然返回一個字符串數組,每一個數組元素對應目錄中的每一個文件或目錄。
表示目錄自己及其父目錄的名稱不包括在結果中。每一個字符串是一個文件名,而不是一條完整路徑。
public String[] list(FilenameFilter filter) 返回一個字符串數組,這些字符串指定此抽象路徑名錶示的目錄中知足指定過濾器的文件和目錄。
除了返回數組中的字符串必須知足過濾器外,此方法的行爲與 list() 方法相同。
若是給定 filter 爲 null,則接受全部名稱。
public File[] listFiles() 返回一個抽象路徑名數組,這些路徑名錶示此抽象路徑名錶示的目錄中的文件。
若是此抽象路徑名不表示一個目錄,那麼此方法將返回 null。
不然返回一個 File 對象數組,每一個數組元素對應目錄中的每一個文件或目錄。
表示目錄自己及其父目錄的名稱不包括在結果中。
不保證所得數組中的相同字符串將以特定順序出現,特別是不保證它們按字母順序出現。
public File[] listFiles(FilenameFilter filter) 除了返回數組中的路徑名必須知足過濾器外,此方法的行爲與 listFiles() 方法相同
若是給定 filter 爲 null,則接受全部路徑名
public File[] listFiles(FileFilter filter) 除了返回數組中的路徑名必須知足過濾器外,此方法的行爲與 listFiles() 方法相同。
若是給定 filter 爲 null,則接受全部路徑名。
public static File[] listRoots()
列出可用的文件系統根。
特定 Java 平臺能夠支持零個或更多個分層組織的文件系統。
每一個文件系統有一個 root 目錄,能夠從這裏到達文件系統中的全部其餘文件。
例如,Windows 平臺爲每一個活動驅動器提供了一個根目錄;
UNIX 平臺只有一個根目錄,即 "/"。
可用文件系統根的設置受各類系統級操做的影響,好比可移動介質的插入和彈出,以及斷開或卸載那些物理磁盤或虛擬磁盤。
 
此方法返回一個 File 對象數組,這些對象表示可用文件系統根的根目錄。
能夠保證本地機器上物理存在的任何文件的規範路徑名都以此方法返回的根之一開始。
 
 
 
list返回的是名稱列表 ,必須是一個目錄
listFile返回的是File列表 必須是一個目錄
image_5b9396eb_4694
image_5b9396eb_10c
ps:直接打印f 調用的是toString  形式,返回的是path
 
過濾器形式的與無參數版本的行爲是相同的,只不過是還要符合過濾器的要求
 
對於FilenameFilter  和 FileFilter,他們是函數式接口
能夠直接使用lambda表達式傳入參數
 
image_5b9396ec_4243
 
對函數式接口不熟悉的能夠翻閱以前關於java8的文章,固然你也能夠匿名內部類或者實現它,顯然lambda表達式是最方便的
下面是調用過程
image_5b9396ec_4430
從上面的調用能夠看得出來,
FilenameFilter  當前抽象路徑名以及全部的名字會傳入到方法中
FileFilter則僅僅只有每一個抽象路徑名
 
測試  FilenameFilter時  下面沒使用到第一個參數,這個你根據實際狀況來
image_5b9396ec_6760
 
ListRoots
image_5b9396ec_55d9

File相關權限設置

public boolean canExecute() 測試應用程序是否能夠執行此抽象路徑名錶示的文件。
public boolean canRead() 測試應用程序是否能夠讀取此抽象路徑名錶示的文件。
public boolean canRead() 測試應用程序是否能夠修改此抽象路徑名錶示的文件。
setExecutable(boolean)
setExecutable(boolean, boolean)
設置此抽象路徑名的全部者或全部用戶的執行權限。
executable - 若是爲 true,則設置容許執行操做的訪問權限;若是爲 false,則不容許執行操做。
ownerOnly - 若是爲 true,則執行權限只適用於全部者的執行權限;不然適用於全部用戶。
 
若是底層文件系統不能區分全部者執行權限與其餘執行權限,那麼不管該參數爲什麼值,執行權限將適用於全部用戶。
 
單參數版本是雙參數版本的快捷默認設置形式
file.setExcutable(arg) 形式的調用與如下調用的行爲徹底相同:file.setExecutable(arg, true) 
也就是單參數默認是設置當前用戶
setReadable(boolean)
setReadable(boolean, boolean)
設置此抽象路徑名的全部者或全部用戶的讀權限。

其他的用法形式同setExecutable
setWritable(boolean)
setWritable(boolean, boolean)
設置此抽象路徑名的全部者或全部用戶的寫權限。
 
其他的用法形式同setExecutable
setExecutable/setReadable/setWritable 用於設置 執行   讀   寫 權限
雙參數版本  第一個參數表示是否容許,第二個參數表示是不是用於全部的用戶
一個參數版本是兩個參數版本的當前用戶的簡化快捷形式
public boolean setReadOnly()
標記此抽象路徑名指定的文件或目錄,從而只能對其進行讀操做。
調用此方法後,能夠保證在被刪除或被標記爲容許寫訪問以前,文件或目錄不會發生更改。
是否能夠刪除某個只讀文件或目錄則取決於底層系統。

public boolean setLastModified(long time) 設置此抽象路徑名指定的文件或目錄的最後一次修改時間。

其餘

public Path toPath() 返回一個java.nio.file.Path   從這個抽象路徑構造的Path對象
1.7新增的
public String toString() 返回此抽象路徑名的路徑名字符串。該字符串就是 getPath() 方法返回的字符串。
    public String toString() {
        return getPath();
    }
 
public URI toURI()
構造一個表示此抽象路徑名的 file: URI。
該 URI 的具體形式與系統有關。若是能夠肯定此抽象路徑名錶示的文件是一個目錄,那麼所得 URI 將以斜槓結束。
 
對於某個給定抽象路徑名 f,可保證:
 
new File( f.toURI()).equals( f.getAbsoluteFile())
 
 
public int compareTo(File pathname) 按字母順序比較兩個抽象路徑名。此方法定義的順序取決於底層系統。
在 UNIX 系統上,比較路徑名時,字母大小寫一般很重要,而在 Microsoft Windows 系統上,這一般不重要。
依賴
public boolean equals(Object obj) 測試此抽象路徑名與給定對象是否相等。
當且僅當該參數不是 null,而是一個與此抽象路徑名錶示相同的文件或目錄的抽象路徑名時,返回 true。
兩個抽象路徑名是否相等取決於底層系統。
在 UNIX 系統上,比較路徑名時,字母大小寫一般很重要,而在 Microsoft Windows 系統上,這一般不重要。 
public int hashCode() 計算此抽象路徑名的哈希碼。
由於抽象路徑名的相等性與系統有關,因此對其哈希碼的計算也與系統有關。
在 UNIX 系統上,抽象路徑名的哈希碼等於其路徑名字符串和十進制值 1234321 的哈希碼的異或。
在 Microsoft Windows 系統上,哈希碼等於其轉換爲小寫的路徑名字符串和十進制值 1234321 的哈希碼的異或。
在將路徑名字符串轉換爲小寫時不考慮語言環境。 
 

FileSystem簡介

 
File中有一個變量fs  類型爲FileSystem
compareTo方法依賴於他
而equals方法又依賴compareTo
hashCode也是依賴他
因此說:
compareTo   equals   hashCode   都依賴於 FileSystem fs
image_5b9396ec_4984
 
其實你在回頭看看整個File文件中,不少個地方都出現了fs的身影

FileSystem究竟是什麼?

操做系統有各自的文件系統,這些文件系統又存在不少差別,而Java 由於是跨平臺的,因此它必需要統一處理這些不一樣平臺文件系統之間的差別,才能往上提供統一的入口。
說白了又是接口來實現統一,不一樣的操做系統實現這個接口,就能夠提供統一的表現形式
 
FileSystem是一個抽象類
image_5b9396ec_1e68
windows下的實現類爲:WinNTFileSystem,在IDE中能夠直接找到
image_5b9396ec_6881
 
可能你只是找到了一個WinNTFileSystem,只有一個要接口還有什麼意思?
若是你目前只看到了一個WinNTFileSystem  那說明你在Windows下
WinNTFileSystem類 和 UnixFileSystem類並非在同一個 JDK 裏面,也就是說它們是分開的
你只能在 Windows 版本的 JDK 中找到 WinNTFileSystem,而在 Linux 版本的 JDK 中找到 UnixFileSystem
一樣地,其餘操做系統也有本身的文件系統實現類。
接下來大體的看下WinNTFileSystem

屬性

private final char slash;//斜槓符號
private final char altSlash;//與slash相反的斜槓
private final char semicolon;//分號
private static String[] driveDirCache = new String[26];//表示驅動盤目錄緩存
private ExpiringCache cache = new ExpiringCache();//用於緩存標準路徑
private ExpiringCache prefixCache = new ExpiringCache();//用於緩存標準路徑前綴
其實slash就是名稱分隔符
semicolon就是路徑分隔符
構造方法中根據系統變量對文件分隔符和路徑分隔符進行初始化
image_5b9396ec_1983
 
isSlash  和 isLetter都很是簡單,簡單的判斷
image_5b9396ec_607
 
判斷是否以slash  開頭,是的話直接返回,不是的話,給他加一個
image_5b9396ec_cb6
 
getSeparator  和 getPathSeparator  就是File中分隔符的來處
image_5b9396ec_7f39
 

路徑的標準化

不光標準化,前面還提到了規範化路徑 File中有方法getCanonicalFile  getCanonicalPath
他們到底都是在說什麼事情呢
 
先說下標準化,看一個例子
咱們給出了一個很奇怪的路徑字符串
"D://////\\\\\\/testFile\\\\///////\\wdwqdwqwd.java"

image_5b9396ec_428
File file = new File("D://////\\\\\\/testFile\\\\///////\\wdwqdwqwd.java");

if (file.exists()){

System.out.println(file.getName());

}

 

image_5b9396ec_7ea4
 
雖然看起來很奇怪,可是不影響程序運行
咱們此時能夠用比較通俗的話來描述這個狀況
咱們給出來了一個亂七八糟的路徑,最終路徑按照當前文件系統的規則,進行了解析,
去除了沒必要要的分隔符 或者可能把錯誤的分隔符進行替換等按照必定的規則
整理出來一個合理的路徑,這就是標準化
 
debug 看下File的構造方法  就知道了
最終他幫咱們正確的解析了路徑,這就是標準化
image_5b9396ec_5748
 
能夠看得出來,標準化,藉助的仍舊是fs  也就是FileSystem
 
在WinNTFileSystem 中的normalize方法就是標準化路徑的一個對外接口
他還有兩個相關的private方法,用於處理細節
方法的具體過程,究竟是怎麼處理的,有興趣的同窗能夠繼續深挖如下
仔細看下注釋也可理解一二
一個標準的win32路徑名,不能包括重複的名稱分隔符(斜槓) UNC除外 ,也不能以名稱分隔符(斜槓)結束
多是一個空的String
規範化Win32路徑名具備便捷的特色:前綴的長度幾乎惟一地標識了路徑的類型
不管它是絕對的仍是相對的
0,1,2,3是分類說明
image_5b9396ec_945
 
如同上面標準化描述的同樣,前綴的長度對於標準化頗有用,這個方法常常被使用
image_5b9396ec_4300
 
 
仍是剛纔的文件夾列表
此次使用另外的構造方法

 

File file = new File("D:\\\\\\/testFile///////\\\\","\\///wdwqdwqwd.java");

if (file.exists()){

System.out.println(file.getName());

}

 

image_5b9396ec_5b48
 
image_5b9396ec_6083
 
因此能夠看得出來resolve作的事情
他要求傳遞進去的兩個字符串都是normal的,因此入參傳遞進去時,就作了處理
雖說兩個都是normal可是兩個拼接起來的狀況仍是極可能須要處理的,
好比子路徑若是以 slash 開頭,丟棄它的頭部,因此子路徑從第2的位置開始
雙參數的resolve就是解決這個問題的
image_5b9396ec_61c9
 
一個參數的resolve
public String resolve(File f)
也是相似的道理
只不過他處理的是一個File
1. 獲取路徑前綴長度
2. 若是頭部長爲2且以\開頭,此時爲 UNC 路徑,直接返回路徑
3. 若是頭部長爲3,則爲本地絕對路徑,直接返回路徑
4. 若是長度爲0,則爲相對路徑,返回用戶路徑+此相對路徑。
5. 若是長度爲1,則爲驅動盤相對路徑,此時嘗試根據用戶路徑獲取驅動盤,存在驅動盤則返回驅動盤+此路徑
   不存在驅動盤則說明用戶路徑是一個 UNC 路徑,返回用戶路徑+此路徑。
6. 若是頭部長度爲2,則爲目錄相對路徑。
   此時先獲取用戶路徑,再根據用戶路徑獲取對應驅動盤,若是路徑以驅動盤開頭,則直接返回用戶路徑+去掉驅動盤後的路徑。
   若是繼續往下則經過 getDriveDirectory 獲取指定驅動盤的工做目錄,
   將驅動盤+:+工做目錄+路徑等拼接起來獲得最終的新路徑,而後還要用安全管理器檢查是否有讀的權限
 
image_5b9396ed_27c1
 
規範化路徑
image_5b9396ed_426d
此處的規範化的含義與File中介紹的返回規範化路徑和文件是一致的
看下File中的調用便可,依賴的就是這個方法
image_5b9396ed_ee0
resolve  normal canonicalize方法本質是同樣的,此處說的本質指的是邏輯切入點
他們都是爲了處理路徑的,只不過是基於不一樣的場景下去解析組織返回路徑
normal最單純
resolve 用於合併路徑,或者將一個File轉換爲路徑
canonicalize 是一個絕對路徑,而且是惟一的形式
getUserPath方法     經過 System 獲取 user.dir 屬性做爲用戶路徑。 
getDrive方法           獲取驅動盤,先獲取路徑頭部長度,再截取驅動盤。
image_5b9396ed_6d90
driveIndex方法
獲取驅動盤的索引值,按照字母順序,好比 a 或 A 則索引值爲0
image_5b9396ed_7916
getDriveDirectory方法
獲取指定驅動盤下的工做目錄,每一個驅動盤都有工做目錄。
先根據驅動盤獲取對應的驅動盤索引
而後嘗試從緩存中讀取,若是讀取獲得直接返回
若是獲取不到, 使用本地方法獲取,而後在緩存起來
 
image_5b9396ed_44b6
fromURIPath主要是完成了路徑的格式化
看代碼的註釋,註釋就是示例程序
image_5b9396ed_286d
 
WinNTFileSystem  還有很多方法,其中有些仍是本地方法,只須要大體瞭解功能便可
不是public的外面也用不了
image_5b9396ed_35f1
不過這個類對於瞭解File 的基本實現是頗有幫助的
由於能夠說File很是很是的依賴他
 
UnixFileSystem的邏輯概念也是相似的,算是廢話了,畢竟都是實現同一個接口
 
本文主要對java中   抽象路徑名  File這一律念進行了詳細的解讀
而且介紹了File 依賴的底層接口  FileSystem  文件系統
不一樣的操做系統有不一樣的文件系統,FileSystem 接口用於提供一致性的操做訪問
不一樣的操做系統提供不一樣的實現類
操做文件依賴底層操做系統,因此File 也必然依賴底層系統
關於文件系統中的規範化標準化可能會有必定的疑惑,由於
其實你跳出來代碼的思惟來看,就是說window平臺對於文件路徑名稱格式自己就有一些的要求
所謂標準化就是適配這種格式,就好像學生時代讓穿校服同樣,那你到了這個學校就換上這個學校的校服,沒什麼好奇怪的
你給出來的一個路徑,想要在某個環境下運行,這個路徑必須是跟本地系統適配的

關於路徑相關的一些補充

根據上面的介紹,很顯然,名稱分隔符和路徑分隔符,不一樣平臺下是不一樣的
File中的分隔符都是獲取的本地系統的
因此不要在你的代碼中寫死某種分隔符,而是使用File給咱們提供的哪幾個public static final定義的分隔符
 
下面說下windows下的一些路徑概念
絕對路徑是一個普遍的概念,它表示的是能夠惟必定位一個文件或文件夾的路徑,
有多種形式的路徑都屬於絕對路徑的範疇 好比,完整路徑(Full path)
咱們平時所說的「絕對路徑」一般就是指完整路徑,它的windows格式以下:
C:\Windows\System32\drivers\etc\hosts
UNC是網絡(主要指局域網)中用於標誌共享文件的路徑
在windows下格式
\\servername\sharename\path\filename
包括計算機名/共享文件夾名/以及共享文件夾下的路徑
相對路徑都是以某一個路徑爲基礎的
純粹的相對路徑
純粹的相對路徑格式以下:
Windows\System32\calc.exe 能夠看獲得,沒有 斜杆  也沒有盤符
相對的位置是,進程的當前文件夾
進程的當前文件夾並非指EXE執行文件所在的文件夾
好比cmd控制檯
cmd.exe程序的位置不會變,可是你能夠切換當前文件夾的位置,切換過的位置就是當前文件夾
斜槓 開頭的相對路徑
斜槓開頭的表示相對於當前文件夾的根路徑,根據上面介紹的當前文件夾,而後肯定他的根路徑
好比當前是C:\Windows  根就是C   相對的就是C

盤符開頭的相對路徑
C:System32\calc.exe 看起來跟完整路徑相似,可是冒號:  後面卻沒有斜槓
這也是一種相對路徑
表示的是進程在該分區上的當前文件夾
進程會保留在每一個分區上的當前文件夾,好比你從 C盤 跳到了D盤,你的當前文件夾變化了
可是你在C盤最後一次的當前文件夾不在變更了,這就是  分區上的當前文件夾
image_5b9396ed_7e20java

calc計算器位於上面的路徑,打開文件能夠執行
切換到別的分區
當你再次切換到C盤的時候,直接就回到了上一次的文件路徑,這就是分區的當前文件夾

linux

 
 
 
linux的絕對路徑是指從根目錄提及的. 例如 /home/somedir/..
而相對路徑則是從當前目錄提及: 即 ./
有4個相對路徑的表示方法:
當前目錄 .
父目錄 ..
某用戶的根目錄 ~user
本身的根目錄 ~
相關文章
相關標籤/搜索