您當前的位置:首頁 > 繪畫

Java中的IO類(二)

作者:由 Stellaria橙子葉 發表于 繪畫時間:2018-10-05

File類

說到IO,就必須提到File類,java。io。File表示檔案系統的一個檔案或者目錄,構造方法為File(String pathname),pathname是與作業系統相關的(例如Windows下用兩個\\表示一個/來分隔目錄,在LInux下用/分隔目錄。)我們可以使用絕對路徑,也可以使用相對路徑。(傳入相對路徑時當前目錄加上相對路徑就是絕對路徑。我們可以用一個。表示當前目錄,兩個。表示的是上一級目錄(傳入相對路徑時當前目錄加上相對路徑就是絕對路徑。我們可以用一個。表示當前目錄,兩個。表示的是上一級目錄)

File物件獲取路徑有三種形式:第一種是構造方法傳入的路徑getPath(),第二種是絕對路徑getAbsolutePath(),第三種是規範路徑getCanonicaPath()。

(規範路徑是將我們傳入路徑中的。轉化為目錄的名字)

Java中的IO類(二)

我們還可以用File物件還可以判斷一個File物件是否為檔案或者目錄,構造一個File物件時,無論我們傳入檔案或者目錄是否存在,都不會發生報錯,因為在構造File物件時,不會有任何磁碟的操作。除非我們使用某些File物件的方法時才會發生磁碟的操作,我們可以用isFile()來判斷物件是否為一個檔案或者使用isDirectory()來判斷目錄是否存在。

當File物件是一個檔案時,我們可以用canRead()/canWrite()/canExcute()來判斷是否允許讀取該檔案/寫入檔案/執行該檔案,我們還可以用length()方法獲取檔案大小,使用createNewFile()建立一個新檔案,而 static createTempFile()可以建立一個臨時檔案,delete()方法可以刪除該檔案 或者使用deleteOnExit()在JVM退出時刪除該檔案。

當物件是一個目錄時,String[] list()方法可以列出目錄下的檔案和子目錄名 File[] listFiles()列出目錄下的檔名, mkdir()可以建立該目錄 ,而mkdirs()不僅可以建立該目錄,而且可以在必要時將不存在的父目錄也創建出來 delete()方法則可以刪除該目錄。

File類的一些方法:

import java。io。File;

public class Test {

public static void main(String[] args) throws Exception{

// TODO Auto-generated method stub

File file=new File(“aa。txt”);//檔案預設就建立在你建立的專案下面,重新整理即可看到

System。out。println(file。exists());//判斷檔案是否存在

file。createNewFile();//建立檔案,不是資料夾

System。out。println(file。exists());//再次判斷是否存在

System。out。println(file。getName());//獲取檔案的名字

System。out。println(file。getAbsolutePath());//獲取檔案的絕對路徑

System。out。println(file。getPath());//獲取檔案的相對路徑

System。out。println(file。getParent());//獲取檔案的父路徑

System。out。println(file。canRead());//檔案是否可讀

System。out。println(file。canWrite());//檔案是否可寫

System。out。println(file。length());//檔案的長度

System。out。println(file。lastModified());//檔案最後一次修改的時間

System。out。println(file。isDirectory());//判斷檔案是否是一個目錄

System。out。println(file。isHidden());//檔案是否隱藏

System。out。println(file。isFile());//判斷檔案是否存在

}

}

InputStream:

Java InputStream類表示有序的位元組流。 換句話說,我們可以將Java InputStream中的資料作為有序的位元組序列讀取。 這在從檔案讀取資料或透過網路接收時非常有用。Java InputStream類是Java IO API中所有輸入流的基類(超類)。 InputStream子類包括FileInputStream,BufferedInputStream和PushbackInputStream等。

InputStream中有兩個重要方法,其中一個重要方法是int read()方法,這是一個過載方法,當沒有引數時,它會讀取一個位元組並將其返回(0~255),如果已經讀到了末位就會返回-1,而int read(byte[]b)讀取若干位元組並填充到byte[]陣列,並返回讀取的位元組數,int read(byte[]b,int off,int len)可以指定byte陣列的偏移量和最大填充數。另外一個重要的方法就是close()方法,它會關閉輸入流。

需要注意的是,read()方法是阻塞(blocking)的,IOStream的程式碼是順序執行的,雖然讀取的時間較長,但我們必須等待讀取完成後才能執行下一段程式碼。

此外,在執行程式碼的過程中,我們有時候會遇到異常,導致我們的InputStream沒有被正確關閉,這會造成資源的浪費,我們可以使用try-finally或者JDK7中提供的try(resource)以保證InputStream正確關閉 。

在InputStream的子類中,比較常用的是FileInputStream以及ByteArrayInputStream ,FileInputStream實現了檔案流輸入

而ByteArrayInputStream可以在記憶體中模擬一個位元組流輸入。

我們以FileInputStream為例,使用try(resource)逐個讀取位元組:

Java中的IO類(二)

或者使用byte陣列快速讀取:

Java中的IO類(二)

OutputStream

類似的,所有的輸出流都有一個超類,那就是OutputStream,OutputStream中也有幾個重要方法,一個是write(),與read()相似,write()也是一個過載方法,當裡面的引數為一個int引數時,它會寫入一個位元組,而void write(byte[] b)會寫入byte陣列的所有位元組,void write(byte[] b,int off ,int len)則寫入byte陣列指定範圍的位元組,要注意的是,write方法也是一個阻塞的方法。同樣的,OutputStream中也有close()方法它會關閉輸出流。此外,OutputStream中還有一個void flush()方法,為了效率考慮,我們通常將內容放在緩衝區中,而flush方法可以將緩衝區中的內容輸出,但通常我們不會手動呼叫這個方法。在緩衝區滿的時候或者close時,程式會自動呼叫這個方法。

例:將byte寫入OutputStream

Java中的IO類(二)

與InputStream相似的是,在OutputStream中也有兩個常用的子類:FileOutputStream和ByteArrayOutputStream,FileOutputStream可以輸出到檔案,而ByteArrayOutputStream可以在記憶體中模擬一個OutputStream

Java中的IO類(二)

FileOutputStream

Java中的IO類(二)

ByteArrayOutputStream

將內容寫入txt中:

Java中的IO類(二)

Filter模式:

其實,除了FileInputStream/FileOutputStream/ByteArrayInputStream/ByteArrayOutputStream,JDK還提供了多種InputStream,他們各有各的功能,例如還有ServletInputStream可以從HTTP中請求讀取資料,Socket。getInputStream可以從TCP連線中讀取資料。在我們實際的開發過程中,往往要實現很多種功能的組合,我們以FileInputStream為例,FileInputStream是一個最終的資料來源,而如果我們要給其增加緩衝功能,我們就可以使用BuffredFileInputStream extends FileInputStream,而如果要增加計算簽名功能,我們就要使用DigestFileInputStream extends FileInputStream……

那麼當我們需要使用多種功能時,我們就需要多種子類組合,而且子類的組合有需要更多的子類。那麼就很容易會出現子類爆炸的情況。

Java中的IO類(二)

為了解決依靠子類繼承會出現的子類過多的情況,JDK把InputStream分為兩類:

Java中的IO類(二)

當我們使用InputStream時,我們就可以跟據情況進行組合,例:

Java中的IO類(二)

FileInputStream是最終的資料來源,BufferedInputStream提供了一個緩衝功能,而GZIPInputStream可以讀取G壓縮檔案。最後我們獲取到的還是一個InputStream物件。

我們來看一下InputSstream的繼承樹:

Java中的IO類(二)

左邊是資料的來源,右邊提供了各種各樣的附加功能

OutputStream的繼承模式也是與之類似的:

Java中的IO類(二)

這種透過組合功能而非繼承的設計模式我們稱之為Filter模式,Filter模式可以在執行的時候動態的增加功能,透過這種模式,我們可以透過少量的類實現多種功能的組合。

標簽: file  檔案  InputStream  System