Java基礎系列8——IO流超詳細總結

該系列博文會告訴你如何從入門到進階,一步步地學習Java基礎知識,並上手進行實戰,接着了解每個Java知識點背後的實現原理,更完整地了解整個Java技術體系,形成自己的知識框架。

在初學Java時,IO流是我遇到的一個很頭疼的東西,Java IO 體系看起來類很多,感覺很複雜,但其實是 IO 涉及的因素太多了。在設計 IO 相關的類時,編寫者也不是從同一個方面考慮的,所以會給人一種很亂的感覺,並且還有設計模式的使用,更加難以使用這些 IO 類,所以特地對 Java 的 IO 做一個總結。

IO流總覽

話不多說,直接上圖:

IO流分類:

按照「流」的數據流向,可以將其化分為:輸入流輸出流

按照「流」中處理數據的單位,可以將其區分為:位元組流字符流。在java中,位元組是佔1個Byte,即8位;而字符是佔2個Byte,即16位。而且,需要注意的是,java的位元組是有符號類型,而字符是無符號類型!

位元組流的抽象基類:

  InputStream,OutputStream

字符流的抽象基類:

  Reader,Writer

由這四個類派生出來的子類名稱都是以其父類名作為子類名的後綴,如InputStream的子類FileInputStream,Reader的子類FileReader。

字符流

Writer:字符輸出流

Writer是字符輸出流的基類,Writer的主要方法如下:

Writer append​(char c) 將指定的字符附加到此作者  Writer append​(CharSequence csq) 將指定的字符序列附加到此作者  Writer append​(CharSequence csq, int start, int end) 將指定字符序列的子序列附加到此作者  abstract void close​() 關閉流,先刷新  abstract void flush​() 刷新流  void write​(char[] cbuf) 寫入一個字符數組。  abstract void write​(char[] cbuf, int off, int len) 寫入字符數組的一部分  void write​(int c) 寫一個字符  void write​(String str) 寫一個字符串  void write​(String str, int off, int len) 寫一個字符串的一部分

我們知道IO流主要是用於操作文件的,但是從上圖中我們發現Writer的直接子類中好像並沒有直接操作文件,但是細心的你注意到,在Writer的子類OutputStreamWriter的子類中有一個類叫做FileWriter,File這個單詞我們很熟悉——文件,大家可以推測一下這個類是可以用於操作文件的,下面我們來學習一下FileWriter的用法

FileWriter

1、FileWriter的構造方法:

OutputStreamWriter​(OutputStream out) 創建一個使用默認字符編碼的OutputStreamWriter  OutputStreamWriter​(OutputStream out, String charsetName) 創建一個使用命名字符集的OutputStreamWriter  OutputStreamWriter​(OutputStream out, Charset cs) 創建一個使用給定字符集的OutputStreamWriter  OutputStreamWriter​(OutputStream out, CharsetEncoder enc) 創建一個使用給定字符集編碼器的OutputStreamWriter  

2、FileWriter的方法列表:

Writer append​(CharSequence csq) 將指定的字符序列附加到此作者。  Writer append​(CharSequence csq, int start, int end) 將指定字符序列的子序列附加到此作者。  void close​() 關閉流,先刷新。  void flush​() 刷新流。  String getEncoding​() 返回此流使用的字符編碼的名稱。  void write​(char[] cbuf, int off, int len) 寫入字符數組的一部分。  void write​(int c) 寫一個字符  void write​(String str, int off, int len) 寫一個字符串的一部分。  

3、FileWriter方法的詳細講解:

例1:創建一個文件demo.txt,然後向裏面寫入字符串abcde

import java.io.*;  class  FileWriterDemo  {  	public static void main(String[] args) throws IOException  	{  		//創建一個FileWriter對象。該對象一被初始化就必須要明確被操作的文件。  		//而且該文件會被創建到指定目錄下。如果該目錄下已有同名文件,將被覆蓋。  		//其實該步就是在明確數據要存放的目的地。  		FileWriter fw = new FileWriter("demo.txt");      		//調用write方法,將字符串寫入到流中。  		fw.write("abcde");    		//刷新流對象中的緩衝中的數據。  		//將數據刷到目的地中。  		//fw.flush();      		//關閉流資源,但是關閉之前會刷新一次內部的緩衝中的數據。  		//將數據刷到目的地中。  		//和flush區別:flush刷新後,流可以繼續使用,close刷新後,會將流關閉。  		fw.close();  	}  }

例2:上面的代碼中我們可以看到有異常產生,但是我們並沒有處理,而是拋出去了,那麼在日常開發中我們不能直接拋出,所以需要對異常進行處理

/*  IO異常的處理方式。  */  import java.io.*;    class  FileWriterDemo2  {  	public static void main(String[] args)  	{  		FileWriter fw = null;  		try  		{  			fw = new FileWriter("demo.txt");//可能會有異常產生  			fw.write("abcdefg");    		}  		catch (IOException e)  		{  			System.out.println("catch:"+e.toString());  		}  		finally  		{  			try  			{  				if(fw!=null)  					fw.close();//可能會有異常產生  			}  			catch (IOException e)  			{  				System.out.println(e.toString());  			}    		}    	}  }

例3:細心的同學可以注意到,上面的那種方式寫入文件時,會將之前的文件覆蓋了,之前文件中寫的內容不存在了,那麼如何在已有的文件後面添加內容

/*  演示對已有文件的數據續寫。  */  import java.io.*;  class  FileWriterDemo3  {  	public static void main(String[] args) throws IOException  	{    		//傳遞一個true參數,代表不覆蓋已有的文件。並在已有文件的末尾處進行數據續寫。  		FileWriter fw = new FileWriter("demo.txt",true);    		fw.write("nihaornxiexie");    		fw.close();  	}  }

BufferedWriter

BufferedWriter 是緩衝字符輸出流。它繼承於Writer。 BufferedWriter 的作用是為其他字符輸出流添加一些緩衝功能,使用BufferedWriter可以提高我們寫入文件的效率。

1、BufferedWriter的構造方法:

BufferedWriter​(Writer out) 創建使用默認大小的輸出緩衝區的緩衝字符輸出流。  BufferedWriter​(Writer out, int sz) 創建一個新的緩衝字符輸出流,使用給定大小的輸出緩衝區。  

2、BufferedWriter的方法列表:

void close​() 關閉流,先刷新。  void flush​() 刷新流。  void newLine​() 寫一行行分隔符。  void write​(char[] cbuf, int off, int len) 寫入字符數組的一部分。  void write​(int c) 寫一個字符  void write​(String s, int off, int len) 寫一個字符串的一部分。  

3、BufferedWriter的方法詳解:

例:

import java.io.*;  class BufferWriterDemo{      public static void main(String[] args) throws IOException {          //創建一個字符寫入流對象。          FileWriter fw = new FileWriter("buf.txt");          //為了提高字符寫入流效率。加入了緩衝技術。  	//只要將需要被提高效率的流對象作為參數傳遞給緩衝區的構造函數即可。          BufferedWriter bw=new BufferedWriter(fw);          char[] c={'a','b','c','d','e'};          bw.write(c,0,4);            //換行          bw.newLine();            //再次寫入          bw.write(c,2,2);            //刷新流          bw.flush();          //其實關閉緩衝區,就是在關閉緩衝區中的流對象。          bw.close();      }  }

CharArrayWriter

CharArrayReader 用於寫入數據符,它繼承於Writer。操作的數據是以字符為單位!

1、CharArrayWriter的構造函數:

CharArrayWriter​() 創建一個新的CharArrayWriter。  CharArrayWriter​(int initialSize) 用指定的初始大小創建一個新的CharArrayWriter。  

2、CharArrayWriter的方法列表:

CharArrayWriter append​(char c) 將指定的字符附加到此作者。  CharArrayWriter append​(CharSequence csq) 將指定的字符序列附加到此作者。  CharArrayWriter append​(CharSequence csq, int start, int end) 將指定字符序列的子序列附加到此作者。  void close​() 關閉流。  void flush​() 沖洗流。  void reset​() 重置緩衝區,以便您可以再次使用它,而不會丟棄已經分配的緩衝區。  int size​() 返回緩衝區的當前大小。  char[] toCharArray​() 返回輸入數據的副本。  String toString​() 將輸入數據轉換為字符串。  void write​(char[] c, int off, int len) 將字符寫入緩衝區。  void write​(int c) 將一個字符寫入緩衝區。  void write​(String str, int off, int len) 將一部分字符串寫入緩衝區。  void writeTo​(Writer out) 將緩衝區的內容寫入另一個字符流。  

FilterWriter

FilterWriter是字符類型的過濾輸出流。

1、FilterWriter的構造函數:

protected  FilterWriter​(Writer out) 創建一個新的過濾的作者。  

2、FilterWriter的方法列表:

void close​() 關閉流,先刷新。  void flush​() 刷新流。  void write​(char[] cbuf, int off, int len) 寫入字符數組的一部分。  void write​(int c) 寫一個字符  void write​(String str, int off, int len) 寫一個字符串的一部分。  

PrintWriter

PrintWriter 是字符類型的打印輸出流,它繼承於Writer。 1、PrintWriter 的構造方法:

PrintWriter​(File file) 使用指定的文件創建一個新的PrintWriter,而不需要自動的線路刷新。  PrintWriter​(File file, String csn) 使用指定的文件和字符集創建一個新的PrintWriter,而不需要自動進行線條刷新。  PrintWriter​(OutputStream out) 從現有的OutputStream創建一個新的PrintWriter,而不需要自動線路刷新。  PrintWriter​(OutputStream out, boolean autoFlush) 從現有的OutputStream創建一個新的PrintWriter。  PrintWriter​(Writer out) 創建一個新的PrintWriter,沒有自動線沖洗。  PrintWriter​(Writer out, boolean autoFlush) 創建一個新的PrintWriter。  PrintWriter​(String fileName) 使用指定的文件名創建一個新的PrintWriter,而不需要自動執行行刷新。  PrintWriter​(String fileName, String csn) 使用指定的文件名和字符集創建一個新的PrintWriter,而不需要自動線路刷新。  

2、PrintWriter 的方法列表:

PrintWriter append​(char c) 將指定的字符附加到此作者。  PrintWriter append​(CharSequence csq) 將指定的字符序列附加到此作者。  PrintWriter append​(CharSequence csq, int start, int end) 將指定字符序列的子序列附加到此作者。  boolean checkError​() 如果流未關閉,請刷新流並檢查其錯誤狀態。  protected void clearError​() 清除此流的錯誤狀態。  void close​() 關閉流並釋放與之相關聯的任何系統資源。  void flush​() 刷新流。  PrintWriter format​(String format, Object... args) 使用指定的格式字符串和參數將格式化的字符串寫入此寫入程序。  PrintWriter format​(Locale l, String format, Object... args) 使用指定的格式字符串和參數將格式化的字符串寫入此寫入程序。  void print​(boolean b) 打印布爾值。  void print​(char c) 打印一個字符  void print​(char[] s) 打印字符數組。  void print​(double d) 打印雙精度浮點數。  void print​(float f) 打印浮點數。  void print​(int i) 打印一個整數。  void print​(long l) 打印一個長整數。  void print​(Object obj) 打印一個對象。  void print​(String s) 打印字符串。  PrintWriter printf​(String format, Object... args) 使用指定的格式字符串和參數將格式化的字符串寫入該writer的方便方法。  PrintWriter printf​(Locale l, String format, Object... args) 使用指定的格式字符串和參數將格式化的字符串寫入該writer的方便方法。  void println​() 通過寫入行分隔符字符串來終止當前行。  void println​(boolean x) 打印一個布爾值,然後終止該行。  void println​(char x) 打印一個字符,然後終止該行。  void println​(char[] x) 打印字符數組,然後終止行。  void println​(double x) 打印雙精度浮點數,然後終止行。  void println​(float x) 打印一個浮點數,然後終止該行。  void println​(int x) 打印一個整數,然後終止該行。  void println​(long x) 打印一個長整型,然後終止行。  void println​(Object x) 打印一個對象,然後終止該行。  void println​(String x) 打印一個字符串,然後終止行。  protected void setError​() 表示發生錯誤。  void write​(char[] buf) 寫入一個字符數組。  void write​(char[] buf, int off, int len) 寫一個字符數組的一部分。  void write​(int c) 寫一個字符  void write​(String s) 寫一個字符串  void write​(String s, int off, int len) 寫一個字符串的一部分。  

Reader:字符輸入流

有輸出流那麼當然就有輸入流,Reader是字符輸入流的基類,Reader的方法列表如下:

abstract void close​() 關閉流並釋放與之相關聯的任何系統資源。  void mark​(int readAheadLimit) 標記流中的當前位置。  boolean markSupported​() 告訴這個流是否支持mark()操作。  int read​() 讀一個字符  int read​(char[] cbuf) 將字符讀入數組。  abstract int read​(char[] cbuf, int off, int len) 將字符讀入數組的一部分。  int read​(CharBuffer target) 嘗試將字符讀入指定的字符緩衝區。  boolean ready​() 告訴這個流是否準備好被讀取。  void reset​() 重置流。  long skip​(long n) 跳過字符  

同Writer一樣,我們先來看一下FileReader的基本操作

FileReader

1、FileReader的構造方法:

FileReader​(File file) 創建一個新的 FileReader ,給出 File讀取。  FileReader​(FileDescriptor fd) 創建一個新的 FileReader ,給予 FileDescriptor從中讀取。  FileReader​(String fileName) 創建一個新的 FileReader ,給定要讀取的文件的名稱。  

2、FileReader的具體使用:

例1:

import java.io.*;    class  FileReaderDemo  {  	public static void main(String[] args) throws IOException  	{  		//創建一個文件讀取流對象,和指定名稱的文件相關聯。  		//要保證該文件是已經存在的,如果不存在,會發生異常FileNotFoundException  		FileReader fr = new FileReader("demo.txt");    		//調用讀取流對象的read方法。  		//read():一次讀一個字符。而且會自動往下讀。    		int ch = 0;    		while((ch=fr.read())!=-1)  		{  			System.out.println("ch="+(char)ch);  		}    		//關閉流  		fr.close();    	}  }

例2:

/*  第二種方式:通過字符數組進行讀取。  */    import java.io.*;    class FileReaderDemo2  {  	public static void main(String[] args) throws IOException  	{  		FileReader fr = new FileReader("demo.txt");      		//定義一個字符數組。用於存儲讀到字符。  		//該read(char[])返回的是讀到字符個數。  		char[] buf = new char[1024];    		int num = 0;  		while((num=fr.read(buf))!=-1)  		{  			System.out.println(new String(buf,0,num));  		}      		fr.close();  	}  }

BufferedReader

1、BufferedReader的構造方法

BufferedReader​(Reader in) 創建使用默認大小的輸入緩衝區的緩衝字符輸入流。  BufferedReader​(Reader in, int sz) 創建使用指定大小的輸入緩衝區的緩衝字符輸入流。  

2、BufferedReader的方法列表:

void close​() 關閉流並釋放與之相關聯的任何系統資源。  Stream<String> lines​() 返回一個 Stream ,其元素是從這個 BufferedReader讀取的行。  void mark​(int readAheadLimit) 標記流中的當前位置。  boolean markSupported​() 告訴這個流是否支持mark()操作。  int read​() 讀一個字符  int read​(char[] cbuf, int off, int len) 將字符讀入數組的一部分。  String readLine​() 讀一行文字。  boolean ready​() 告訴這個流是否準備好被讀取。  void reset​() 將流重置為最近的標記。  long skip​(long n) 跳過字符  

3、BufferedReader的具體使用:

例1:

/*  字符讀取流緩衝區:  該緩衝區提供了一個一次讀一行的方法 readLine,方便於對文本數據的獲取。  當返回null時,表示讀到文件末尾。    readLine方法返回的時候只返回回車符之前的數據內容。並不返回回車符。      */    import java.io.*;    class  BufferedReaderDemo  {  	public static void main(String[] args) throws IOException  	{  		//創建一個讀取流對象和文件相關聯。  		FileReader fr = new FileReader("buf.txt");    		//為了提高效率。加入緩衝技術。將字符讀取流對象作為參數傳遞給緩衝對象的構造函數。  		BufferedReader bufr = new BufferedReader(fr);      		String line = null;    		while((line=bufr.readLine())!=null)  		{  			System.out.print(line);  		}              //關閉流  		bufr.close();  	}    }

例2:通過緩衝區複製文件:

/*  通過緩衝區複製一個.java文件。    */  import java.io.*;    class  CopyTextByBuf  {  	public static void main(String[] args)  	{  		BufferedReader bufr = null;  		BufferedWriter bufw = null;    		try  		{  			bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));  			bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));    			String line = null;    			while((line=bufr.readLine())!=null)  			{  				bufw.write(line);  				bufw.newLine();  				bufw.flush();    			}  		}  		catch (IOException e)  		{  			throw new RuntimeException("讀寫失敗");  		}  		finally  		{  			try  			{  				if(bufr!=null)  					bufr.close();  			}  			catch (IOException e)  			{  				throw new RuntimeException("讀取關閉失敗");  			}  			try  			{  				if(bufw!=null)  					bufw.close();  			}  			catch (IOException e)  			{  				throw new RuntimeException("寫入關閉失敗");  			}  		}  	}  }

位元組流

位元組流的基本操作和字符流類相同,但它不僅可以操作字符,還可以操作其他媒體文件

InputStream位元組輸入流

InputStream類是位元組輸入流的抽象類,是所有位元組輸入流的父類,InputStream類具有層次結構如下圖所示:

InputStream的常用方法:

int available​() 從下一次調用此輸入流的方法返回可從該輸入流讀取(或跳過)的位元組數,而不會阻塞。  void close​() 關閉此輸入流並釋放與流相關聯的任何系統資源。  void mark​(int readlimit) 標記此輸入流中的當前位置。  boolean markSupported​() 測試此輸入流是否支持 mark和 reset方法。  abstract int read​() 從輸入流讀取數據的下一個位元組。  int read​(byte[] b) 從輸入流中讀取一些位元組數,並將它們存儲到緩衝器陣列 b 。  int read​(byte[] b, int off, int len) 從輸入流讀取最多 len個位元組的數據到位元組數組。  byte[] readAllBytes​() 從輸入流讀取所有剩餘位元組。  int readNBytes​(byte[] b, int off, int len) 將所請求的位元組數從輸入流讀入給定的位元組數組。  void reset​() 將此流重新定位到最後在此輸入流上調用 mark方法時的位置。  long skip​(long n) 跳過並丟棄來自此輸入流的 n位元組的數據。  long transferTo​(OutputStream out) 從該輸入流中讀取所有位元組,並按讀取的順序將位元組寫入給定的輸出流。  

FileInputStream

1、FileInputStream的構造方法:

FileInputStream​(File file) 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。  FileInputStream​(FileDescriptor fdObj) 通過使用文件描述符 fdObj創建 FileInputStream ,該文件描述符表示與文件系統中的實際文件的現有連接。  FileInputStream​(String name) 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。  

2、FileInputStream的方法列表:

int available​() 返回從此輸入流中可以讀取(或跳過)的剩餘位元組數的估計值,而不會被下一次調用此輸入流的方法阻塞。  void close​() 關閉此文件輸入流並釋放與流相關聯的任何系統資源。  protected void finalize​() 已過時。  finalize方法已被棄用。 為了執行清理而覆蓋finalize子類應該修改為使用替代清理機制,並刪除覆蓋的finalize方法。 當覆蓋finalize方法時,其實現必須明確確保按照super.finalize()所述調用super.finalize() 。 有關遷移選項的更多信息,請參閱Object.finalize()的規範。  FileChannel getChannel​() 返回與此文件輸入流相關聯的唯一的FileChannel對象。  FileDescriptor getFD​() 返回表示與此 FileInputStream正在使用的文件系統中的實際文件的連接的 FileDescriptor對象。  int read​() 從該輸入流讀取一個位元組的數據。  int read​(byte[] b) 從該輸入流讀取最多 b.length個位元組的數據到一個位元組數組。  int read​(byte[] b, int off, int len) 從該輸入流讀取最多 len個位元組的數據到位元組數組。  long skip​(long n) 跳過並從輸入流中丟棄 n位元組的數據。  

3、FileInputStream的具體使用:

import java.io.*;  class  FileStream  {  	public static void main(String[] args) throws IOException  	{  		readFile_3();  	}    	//打開文件,一次讀取剛剛好內容的位元組  	public static void readFile_3()throws IOException  	{  		FileInputStream fis = new FileInputStream("fos.txt");    		//available()返回從此輸入流中可以讀取(或跳過)的剩餘位元組數的估計值,而不會被下一次調用此輸入流的方法阻塞。  		byte[] buf = new byte[fis.available()];//定義一個剛剛好的緩衝區。不用在循環了。    		fis.read(buf);    		System.out.println(new String(buf));    		fis.close();  	}      	//打開文件,一次讀取多個位元組  	public static void readFile_2()throws IOException  	{  		FileInputStream fis = new FileInputStream("fos.txt");    		byte[] buf = new byte[1024];  		int len = 0;  		while((len=fis.read(buf))!=-1)  		{  			System.out.println(new String(buf,0,len));  		}    		fis.close();    	}      	//打開文件,一次讀取一個位元組  	public static void readFile_1()throws IOException  	{    		FileInputStream fis = new FileInputStream("fos.txt");    		int ch = 0;    		while((ch=fis.read())!=-1)  		{  			System.out.println((char)ch);  		}    		fis.close();  	}    }

OutputStream 位元組輸出流

OutputStream位元組輸出流的方法:

void close​() 關閉此輸出流並釋放與此流相關聯的任何系統資源。  void flush​() 刷新此輸出流並強制任何緩衝的輸出位元組被寫出。  void write​(byte[] b) 將 b.length位元組從指定的位元組數組寫入此輸出流。  void write​(byte[] b, int off, int len) 從指定的位元組數組寫入 len位元組,從偏移量 off開始輸出到此輸出流。  abstract void write​(int b) 將指定的位元組寫入此輸出流。  

FileOutPutStream

1、FileOutPutStream的構造方法:

FileOutputStream​(File file) 創建文件輸出流以寫入由指定的 File對象表示的文件。  FileOutputStream​(FileDescriptor fdObj) 創建文件輸出流以寫入指定的文件描述符,表示與文件系統中實際文件的現有連接。  FileOutputStream​(File file, boolean append) 創建文件輸出流以寫入由指定的 File對象表示的文件。  FileOutputStream​(String name) 創建文件輸出流以指定的名稱寫入文件。  FileOutputStream​(String name, boolean append) 創建文件輸出流以指定的名稱寫入文件。  

2、FileOutPutStream的方法列表:

void close​() 關閉此文件輸出流並釋放與此流相關聯的任何系統資源。  protected void finalize​() 已過時。  finalize方法已被棄用。 為了執行清理,覆蓋finalize子類應被修改為使用替代的清理機制,並刪除覆蓋的finalize方法。 當覆蓋finalize方法時,其實現必須明確確保按照super.finalize()中所述調用super.finalize() 。 有關遷移選項的更多信息,請參閱Object.finalize()的規範。  FileChannel getChannel​() 返回與此文件輸出流相關聯的唯一的FileChannel對象。  FileDescriptor getFD​() 返回與此流相關聯的文件描述符。  void write​(byte[] b) 將 b.length位元組從指定的位元組數組寫入此文件輸出流。  void write​(byte[] b, int off, int len) 將 len位元組從指定的位元組數組開始,從偏移量 off開始寫入此文件輸出流。  void write​(int b) 將指定的位元組寫入此文件輸出流。  

3、FileOutPutStream的具體使用:

import java.io.*;    public class FileStreamTest {        private static final String FileName = "file.txt";        public static void main(String[] args) {          testWrite();      }        /**       * FileOutputStream 演示函數       *       * 運行結果:       * 在源碼所在目錄生成文件"file.txt",文件內容是「abcdefghijklmnopqrstuvwxyz0123456789」       *       * 加入,我們將 FileOutputStream fileOut2 = new FileOutputStream(file, true);       *       修改為 FileOutputStream fileOut2 = new FileOutputStream(file, false);       * 然後再執行程序,「file.txt」的內容變成"0123456789"。       * 原因是:       * (01) FileOutputStream fileOut2 = new FileOutputStream(file, true);       *      它是以「追加模式」將內容寫入文件的。即寫入的內容,追加到原始的內容之後。       * (02) FileOutputStream fileOut2 = new FileOutputStream(file, false);       *      它是以「新建模式」將內容寫入文件的。即刪除文件原始的內容之後,再重新寫入。       */      public static void testWrite() {          try {              // 創建文件「file.txt」對應File對象              File file = new File(FileName);              // 創建文件「file.txt」對應的FileOutputStream對象,默認是關閉「追加模式」              FileOutputStream fileOut1 = new FileOutputStream(file);              // 創建FileOutputStream對應的PrintStream,方便操作。PrintStream的寫入接口更便利              PrintStream out1 = new PrintStream(fileOut1);              // 向「文件中」寫入26個字母              out1.print("abcdefghijklmnopqrstuvwxyz");              out1.close();                // 創建文件「file.txt」對應的FileOutputStream對象,打開「追加模式」              FileOutputStream fileOut2 = new FileOutputStream(file, true);              // 創建FileOutputStream對應的PrintStream,方便操作。PrintStream的寫入接口更便利              PrintStream out2 = new PrintStream(fileOut2);              // 向「文件中」寫入"0123456789"+換行符              out2.println("0123456789");              out2.close();            } catch(IOException e) {              e.printStackTrace();          }      }      }

File

JavaIo流中還有一個非常常用的類:File。

File 是「文件」和「目錄路徑名」的抽象表示形式。 File 直接繼承於Object,實現了Serializable接口和Comparable接口。實現Serializable接口,意味着File對象支持序列化操作。而實現Comparable接口,意味着File對象之間可以比較大小;File能直接被存儲在有序集合(如TreeSet、TreeMap中)。

1、File的構造方法:

File​(File parent, String child) 從父抽象路徑名和子路徑名字符串創建新的 File實例。  File​(String pathname) 通過將給定的路徑名字符串轉換為抽象路徑名來創建新的 File實例。  File​(String parent, String child) 從父路徑名字符串和子路徑名字符串創建新的 File實例。  File​(URI uri) 通過將給定的 file: URI轉換為抽象路徑名來創建新的 File實例。  

2、File的方法列表:

boolean canExecute​() 測試應用程序是否可以執行此抽象路徑名表示的文件。  boolean canRead​() 測試應用程序是否可以讀取由此抽象路徑名表示的文件。  boolean canWrite​() 測試應用程序是否可以修改由此抽象路徑名表示的文件。  int compareTo​(File pathname) 比較兩個抽象的路徑名字典。  boolean createNewFile​() 當且僅當具有該名稱的文件尚不存在時,原子地創建一個由該抽象路徑名命名的新的空文件。  static File createTempFile​(String prefix, String suffix) 在默認臨時文件目錄中創建一個空文件,使用給定的前綴和後綴生成其名稱。  static File createTempFile​(String prefix, String suffix, File directory) 在指定的目錄中創建一個新的空文件,使用給定的前綴和後綴字符串生成其名稱。  boolean delete​() 刪除由此抽象路徑名表示的文件或目錄。  void deleteOnExit​() 請求在虛擬機終止時刪除由此抽象路徑名表示的文件或目錄。  boolean equals​(Object obj) 測試此抽象路徑名與給定對象的相等性。  boolean exists​() 測試此抽象路徑名表示的文件或目錄是否存在。  File getAbsoluteFile​() 返回此抽象路徑名的絕對形式。  String getAbsolutePath​() 返回此抽象路徑名的絕對路徑名字符串。  File getCanonicalFile​() 返回此抽象路徑名的規範形式。  String getCanonicalPath​() 返回此抽象路徑名的規範路徑名字符串。  long getFreeSpace​() 通過此抽象路徑名返回分區 named中未分配位元組的數量。  String getName​() 返回由此抽象路徑名表示的文件或目錄的名稱。  String getParent​() 返回此抽象路徑名的父目錄的路徑名字符串,如果此路徑名未命名為父目錄,則返回 null 。  File getParentFile​() 返回此抽象路徑名的父目錄的抽象路徑名,如果此路徑名不指定父目錄,則返回 null 。  String getPath​() 將此抽象路徑名轉換為路徑名字符串。  long getTotalSpace​() 通過此抽象路徑名返回分區 named的大小。  long getUsableSpace​() 通過此抽象路徑名返回分區 named上此虛擬機可用的位元組數。  int hashCode​() 計算此抽象路徑名的哈希碼。  boolean isAbsolute​() 測試這個抽象路徑名是否是絕對的。  boolean isDirectory​() 測試此抽象路徑名表示的文件是否為目錄。  boolean isFile​() 測試此抽象路徑名表示的文件是否為普通文件。  boolean isHidden​() 測試此抽象路徑名命名的文件是否為隱藏文件。  long lastModified​() 返回此抽象路徑名表示的文件上次修改的時間。  long length​() 返回由此抽象路徑名表示的文件的長度。  String[] list​() 返回一個字符串數組,命名由此抽象路徑名表示的目錄中的文件和目錄。  String[] list​(FilenameFilter filter) 返回一個字符串數組,命名由此抽象路徑名表示的目錄中滿足指定過濾器的文件和目錄。  File[] listFiles​() 返回一個抽象路徑名數組,表示由該抽象路徑名表示的目錄中的文件。  File[] listFiles​(FileFilter filter) 返回一個抽象路徑名數組,表示由此抽象路徑名表示的滿足指定過濾器的目錄中的文件和目錄。  File[] listFiles​(FilenameFilter filter) 返回一個抽象路徑名數組,表示由此抽象路徑名表示的滿足指定過濾器的目錄中的文件和目錄。  static File[] listRoots​() 列出可用的文件系統根。  boolean mkdir​() 創建由此抽象路徑名命名的目錄。  boolean mkdirs​() 創建由此抽象路徑名命名的目錄,包括任何必需但不存在的父目錄。  boolean renameTo​(File dest) 重命名由此抽象路徑名表示的文件。  boolean setExecutable​(boolean executable) 為此抽象路徑名設置所有者的執行權限的便利方法。  boolean setExecutable​(boolean executable, boolean ownerOnly) 設置該抽象路徑名的所有者或每個人的執行權限。  boolean setLastModified​(long time) 設置由此抽象路徑名命名的文件或目錄的最後修改時間。  boolean setReadable​(boolean readable) 一種方便的方法來設置所有者對此抽象路徑名的讀取權限。  boolean setReadable​(boolean readable, boolean ownerOnly) 設置此抽象路徑名的所有者或每個人的讀取權限。  boolean setReadOnly​() 標記由此抽象路徑名命名的文件或目錄,以便只允許讀取操作。  boolean setWritable​(boolean writable) 一種方便的方法來設置所有者對此抽象路徑名的寫入權限。  boolean setWritable​(boolean writable, boolean ownerOnly) 設置此抽象路徑名的所有者或每個人的寫入權限。  Path toPath​() 返回從此抽象路徑構造的一個java.nio.file.Path對象。  String toString​() 返回此抽象路徑名的路徑名字符串。  URI toURI​() 構造一個表示此抽象路徑名的 file: URI。  URL toURL​() 已過時。 此方法不會自動轉義URL中非法的字符。 建議在新的代碼轉換的抽象路徑到URL通過先轉換成URI,經由toURI方法,然後經由轉換URI為URL URI.toURL方法。  

3、File的具體使用:

例1:

import java.io.*;    /*  File類常見方法:  1,創建。  	boolean createNewFile():在指定位置創建文件,如果該文件已經存在,則不創建,返回false。  						和輸出流不一樣,輸出流對象一建立創建文件。而且文件已經存在,會覆蓋。    	boolean mkdir():創建文件夾。  	boolean mkdirs():創建多級文件夾。  2,刪除。  	boolean delete():刪除失敗返回false。如果文件正在被使用,則刪除不了返回falsel。  	void deleteOnExit();在程序退出時刪除指定文件。      3,判斷。  	boolean exists() :文件是否存在.  	isFile():  	isDirectory();  	isHidden();  	isAbsolute();    4,獲取信息。  	getName():  	getPath():  	getParent():    	getAbsolutePath()  	long lastModified()  	long length()    */      class FileDemo  {  	public static void main(String[] args) throws IOException  	{  		method_5();  	}    	public static void method_5()  	{  		File f1 = new File("c:\Test.java");  		File f2 = new File("d:\hahah.java");    		sop("rename:"+f2.renameTo(f1));    	}    	public static void method_4()  	{  		File f = new File("file.txt");    		sop("path:"+f.getPath());  		sop("abspath:"+f.getAbsolutePath());  		//該方法返回的是絕對路徑中的父目錄。如果獲取的是相對路徑,返回null。  		//如果相對路徑中有上一層目錄那麼該目錄就是返回結果。  		sop("parent:"+f.getParent());      	}    	public static void method_3()throws IOException  	{  		File f = new File("d:\java1223\day20\file2.txt");  		//f.createNewFile();    		//f.mkdir();    		//記住在判斷文件對象是否是文件或者目的時,必須要先判斷該文件對象封裝的內容是否存在。  		//通過exists判斷。  		sop("dir:"+f.isDirectory());  		sop("file:"+f.isFile());    		sop(f.isAbsolute());  	}      	public static void method_2()  	{  		File f = new File("file.txt");    		//sop("exists:"+f.exists());    		//sop("execute:"+f.canExecute());    		//創建文件夾  		File dir = new File("abc\kkk\a\a\dd\ee\qq\aaa");    		sop("mkdir:"+dir.mkdirs());  	}      	public static void method_1()throws IOException  	{  		File f = new File("file.txt");  		sop("create:"+f.createNewFile());  		//sop("delete:"+f.delete());    	}      	//創建File對象  	public static void consMethod()  	{  		//將a.txt封裝成file對象。可以將已有的和為出現的文件或者文件夾封裝成對象。  		File f1 = new File("a.txt");    		File f2 = new File("c:\abc","b.txt");    		File d = new File("c:\abc");  		File f3 = new File(d,"c.txt");    		sop("f1:"+f1);  		sop("f2:"+f2);  		sop("f3:"+f3);    		File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");      	}    	public static void sop(Object obj)  	{  		System.out.println(obj);  	}  }

例2:遞歸列出指定目錄下的文件或者文件夾

/*  列出指定目錄下文件或者文件夾,包含子目錄中的內容。  也就是列出指定目錄下所有內容。    因為目錄中還有目錄,只要使用同一個列出目錄功能的函數完成即可。  在列出過程中出現的還是目錄的話,還可以再次調用本功能。  也就是函數自身調用自身。  這種表現形式,或者編程手法,稱為遞歸。    遞歸要注意:  1,限定條件。    2,要注意遞歸的次數。盡量避免內存溢出。      */    import java.io.*;    class FileDemo3  {  	public static void main(String[] args)  	{  		File dir = new File("E:\Book");  		showDir(dir,0);    	}  	public static String getLevel(int level)  	{  		StringBuilder sb = new StringBuilder();  		sb.append("|--");  		for(int x=0; x<level; x++)  		{  			//sb.append("|--");  			sb.insert(0,"|  ");    		}  		return sb.toString();  	}  	public static void showDir(File dir,int level)  	{    		System.out.println(getLevel(level)+dir.getName());    		level++;  		File[] files = dir.listFiles();  		for(int x=0; x<files.length; x++)  		{  			if(files[x].isDirectory())  				showDir(files[x],level);  			else  				System.out.println(getLevel(level)+files[x]);  		}  	}          }