#目錄
一、File 類
二、IO流
三、字節輸出流
四、字節輸入流
五、字節流文件復制
六、字符輸出流
七、字符輸入流
八、字符流復制文本文件
##一、File 類
###1. 概述
文件 和 目錄路徑名 的抽象表達形式
Java中把文件或者目錄(文件夾)都封裝成 File對象
我們要去操作硬盤上的文件,或者文件夾只要找到 File這個類即可
File類對象,只是路徑名的 抽象表示形式,即使該文件在操作系統上并不物理存在,也可以創建這個路徑所表示的File對象
###2. 構造方法
File(String pathname):通過給定 路徑名字符串 轉換為 抽象路徑名 來創建一個新 File 實例
windows中的路徑或文件名不區分大小寫,但是最好別這樣,跨平臺可能會出現問題
File(String parent, String child):根據 parent 路徑名字符串 和 child 路徑名字符串,創建一個新 File 實例
好處: 單獨操作父路徑和子路徑
File(File parent, String child):根據 parent 抽象路徑名 和 child 路徑名字符串,創建一個 File 實例
好處: 父路徑是File類型,父路徑可以直接調用File類方法
public class Test {public static void main(String[] args) {/** File(String pathname)* 傳遞路徑名: 可以寫到文件夾,可以寫到一個文件*/File file = new File("f:\\a.txt");System.out.println(file);/** File(String parent, String child)* 傳遞字符串父路徑,字符串子路徑*/File file = new File("f:\\", "a.txt");System.out.println(file);/** File(File parent, String child)* 傳遞傳遞File類型父路徑,字符串子路徑*/File parent = new File("f:");//帶不帶"\\"都可以File file = new File(parent, "a.txt");System.out.println(file);}
}
###3. File 類成員方法
—創建功能—
public boolean createNewFile():創建文件,如果文件已存在,不再創建
public boolean mkdir():創建單級文件夾,如果文件夾已存在,不再創建
public boolean mkdirs():創建多級文件夾,文件夾已經存在了,不在創建
mkdirs() 也可以創建單級文件夾,所以推薦使用 mkdirs()
—刪除功能—
public boolean delete(): 刪除文件或者文件夾,不走回收站,直接從硬盤刪除!
如果此路徑名表示一個目錄,則該目錄 必須為空 才能刪除。
—重命名功能—
public boolean renameTo(File dest): 重新命名文件
—判斷功能—
public boolean isFile() :判斷File構造方法中封裝的路徑是不是文件
public boolean isDirectory():判斷File構造方法中封裝的路徑是不是文件夾
public boolean exists(): 判斷File構造方法中封裝的路徑是否存在
public boolean canRead() :讀權限
public boolean canWrite() :寫權限
public boolean isHidden() :是否隱藏
—基本獲取功能—
public String getAbsolutePath():獲取絕對路徑,返回 String 對象
public File getAbsoluteFile():獲取絕對路徑,返回 file 對象(推薦使用)
eclipse和 IDEA環境中,寫一個相對路徑,獲取的絕對位置是工程根目錄
public String getPath():將抽象路徑名轉換為字符串(就相當于 toString)
public String getName():返回路徑中表示的文件名或者文件夾名 (獲取路徑中的最后部分的名字)
public long length() :返回路徑中表示的文件的字節數(文件夾為 0)
public long lastModified() :上次修改的時間
String getParent(): 獲取父路徑,返回String對象
File getParentFile(): 獲取父路徑,返回File對象(推薦使用)
###4. File類高級獲取功能
public String[] list()
獲取到 File 構造方法中封裝的路徑中的文件和文件夾名 (遍歷一個目錄),返回只有名字
如果此抽象路徑名不表示一個目錄,那么此方法將返回 null
返回的是一個字符串數組
不會遞歸的獲取子目錄中的信息(文件或者目錄的名稱)
public File[] listFiles()
獲取到 File 構造方法中封裝的路徑中的文件和文件夾名 (遍歷一個目錄),返回的是目錄或者文件的 全路徑
返回一個 File對象數組
不會遞歸的獲取子目錄中的信息(文件或者目錄的名稱)
注意:在獲取指定目錄下的文件或者文件夾時必須滿足下面兩個條件
1,指定的目錄必須存在
2,指定的必須是目錄。否則容易引發 返回數組為null,出現NullPointerException
###5. 文件過濾器
listFiles(FileFilter filter) : 傳遞 FileFilter 接口的實現類
FileFilter 接口:
必須自定義 FileFilter 接口實現類,重寫抽象方法,然后將接口實現類對象傳遞到遍歷方法 listFiles
boolean accept(File pathname) 返回 true 滿足條件,回false不滿足過濾條件
過濾器中的 accept() 方法接受一個參數,這個參數就當前文件或文件夾對象(全路徑)
FilenameFilter接口:
過濾器中的 accept() 接受兩個參數,一個當前文件或文件夾所在的路徑,一個是當前文件或文件夾對象的名稱
boolean accept(File dir, String name) 返回true滿足條件,回false不滿足過濾條件
當我們需要過濾文件名稱時就可以使用 FilenameFilter 這個過濾器,當我們想對當前文件或文件夾進行過濾,就可以使用 FileFilter
對于一個目錄下,文件或文件目錄的篩選工作代碼:
不變——篩選過程
變化——篩選條件
原理分析
listFiles() 遍歷目錄的同時,獲取到了文件名全路徑,調用過濾器的方法 accept(),將獲取到的路徑傳遞給 accept(),accept() 方法接收了參數,參數是 listFiles 傳遞來的,在 accept()方法中,進行判斷,如果滿足過濾條件,返回true,否則返回false,一旦方法返回了true,listFiles 就將路徑保存到 File數組 中
###6. 遞歸遍歷全目錄
public class FileDemo {public static void main(String[] args) {File dir = new File("E:\\a");getAllDir(dir);}// 定義方法,實現目錄的全遍歷private static void getAllDir(File dir) {//調用方法listFiles()對目錄,dir進行遍歷File[] fileArr = dir.listFiles();for(File f : fileArr){//判斷變量f表示的路徑是不是文件夾,是,則遞歸遍歷if(f.isDirectory()){getAllDir(f);}else{System.out.println(f);}}}
}
##二、IO流
###1. 概述
IO流用來處理設備之間的 數據傳輸
Java對數據的操作是通過 流 的方式
Java用于操作流的對象都在 IO包 中(input/output)
Output操作:把內存中的數據存儲到持久化設備上這個動作稱為輸出(寫)
Input操作:把持久設備上的數據讀取到內存中的這個動作稱為輸入(讀)
流的分類:
流按流向分為兩種:
輸出流:內存——>外設(寫出數據)
輸入流:磁盤——>內存(讀入數據)
流按操作類型分為兩種:
字節流:字節流可以操作任何數據,因為在計算機中任何數據都是以字節的形式存儲的
字符流:字符流只能操作純字符數據,比較方便。
###2. IO流常用父類
字節流的抽象父類:InputStream ,OutputStream
字符流的抽象父類:Reader , Writer
##三、字節輸出流
###1. 概述
java.io.OutputStream 此抽象類,是表示輸出字節流的所有類的超類。操作的數據都是 字節
##2. OutputStream 的核心方法:
void close(): 關閉此輸出流并釋放與此流有關的所有系統資源。
close的常規協定:該方法將關閉輸出流。關閉的流不能執行輸出操作,也不能重新打開。
如果流對象建立失敗了,需要關閉資源嗎?
new 對象的時候,失敗了,沒有占用系統資源;釋放資源的時候,對流對象判斷null,變量不是null,對象建立成功,需要關閉資源
write(byte[] b): 將 b.length 個字節從指定的 byte 數組寫入此輸出流
write(byte[] b, int off, int len):將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
write(int b): 將指定的字節寫入此輸出流。write 的常規協定:向輸出流寫入一個字節。要寫入的字節是參數 b 的八個低位。b 的 24 個高位將被忽略。
###3. FileOutputStream 類
####(1) 構造方法
FileOutputStream(File file) :創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流。
FileOutputStream(File file, boolean append): 創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流,以追加的方式寫入。
FileOutputStream(String name) :創建一個向具有指定名稱的文件中寫入數據的輸出文件流。
FileOutputStream(String name, boolean append) :創建一個向具有指定 name 的文件中寫入數據的輸出文件流,以追加的方式寫入。
####(2) 流對象的使用步驟:
創建流子類的對象,綁定數據目的
調用流對象的方法write寫
close釋放資源
注意事項:流對象的構造方法,可以創建文件,如果文件存在,直接覆蓋
public class IoDemo {public static void main(String[] args) throws IOException {//創建流子類的對象,綁定數據目的FileOutputStream fos = new FileOutputStream("E:\\a.txt");//用write方法寫數據//寫一個字節fos.write(100); //d//寫字節數組byte[] bytes = {65,66,67,68}; //ABCDfos.write(bytes);//寫字節的一部分,開始索引,寫幾個fos.write(bytes,1,1); //B//寫入字節數組的簡便方式//寫字符串fos.write("Hello".getBytes());//關閉資源fos.close();}
}
###4. 文件的續寫和換行
####(1)實現數據的換行
在文件中,寫入換行符號換行: \r\n
\r\n 可以寫在上一行的末尾, 也可以寫在下一行的開頭
fos.write("hello\r\n".getBytes());
####(2)關于數據的追加寫入
默認情況下,當一個文件輸出流對象,指向一個文件的時候,會清空文件內容
必須使用特殊的構造方法實現文件的追加寫入,FileOutputStream構造方法, 的第二個參數中加入 true
//實現追加寫入:
FileOutputStream fos = new FileOutputStream(file, true);
###5. IO異常的處理
一些細節:
保證流對象變量,作用域足夠
catch里面處理異常
輸出異常的信息,目的看到哪里出現了問題,停下程序,從新嘗試
如果流對象建立失敗了,需要關閉資源嗎
new 對象的時候,失敗了,沒有占用系統資源;釋放資源的時候,對流對象判斷 null;變量不是 null,對象建立成功,需要關閉資源
public class FileOutputStreamDemo3 {public static void main(String[] args) {File file = new File("c:\\file.txt");//try 外面聲明變量,try 里面建立對象,為了提升流對象作用域//定義FileOutputStream的引用FileOutputStream fos = null;try {//創建FileOutputStream對象fos = new FileOutputStream(file);//寫出數據fos.write("abcde".getBytes());} catch (IOException e) {System.out.println(e.toString() + "----");throw new RuntimeException("文件寫入失敗,重試");} finally {//一定要判斷fos是否為null,只有不為null時,才可以關閉資源if (fos != null) {try {fos.close();} catch (IOException e) {throw new RuntimeException("關閉資源失敗");}}}}
}
##四、字節輸入流
###1. 概述
java.io.InputStream: 此抽象類是表示字節輸入流的所有類的超類。讀取任意文件,每次只讀取1個字節
###2. 核心方法
abstract int read():讀取一個字節
read()方法的特點:read() 執行一次,就會自動讀取下一個字節,返回值是讀取到的字節, 讀取到結尾返回 -1
public class IoDemo {public static void main(String[] args) throws IOException {//創建字節輸入流的子類對象FileInputStream fis = new FileInputStream("E:\\a.txt"); //ABCD//讀取一個字節,調用read方法,返回int//使用循環方式,讀取文件,循環結束的條件:read() 返回 -1int len = 0; //接收read()的返回值while((len = fis.read()) != -1){System.out.print((char)len); //可以轉換成字符}//關閉資源fis.close();}
}
int read(byte[] b):讀取一定數量的字節,并將其存儲在緩沖區數組 b 中
int read(byte[] b, int off, int len) :讀取最多 len 個字節,存入 byte 數組。
數組的作用:緩沖的作用, 提高效率
read 返回的 int,表示讀取到多少個有效的字節數
public class IoDemo {public static void main(String[] args) throws IOException {//創建字節輸入流的子類對象FileInputStream fis = new FileInputStream("E:\\a.txt"); //創建字節數組byte[] b = new byte[1024];int len = 0;while((len = fis.read(b)) != -1){System.out.print(new String(b,0,len)); //使用String的構造方法,轉為字符串}//關閉資源fis.close();}
}
###3. FileInputStream 類
####(1)構造方法
為這個流對象 綁定數據源
FileInputStream(File file)
FileInputStream(String name)
參數:File對象 和 String對象
####(2)輸入流讀取文件的步驟
創建字節輸入流的子類對象
調用讀取方法 read 讀取
關閉資源
####(3)讀取數據的方式:
第一種方式:一次讀取一個字節數據
第二種方式:一次讀取一個字節數組
第二種方式效率更高,每次讀取都會和操作系統發生一次交互,第二種方式每次可以讀取多個數據,提高了操作效率
####4、釋放資源的另一種方式
//1.第一種釋放資源的方式 closeQuietly
//釋放輸入流資源
closeQuietly(fis);
//釋放輸出流對象
closeQuietly(fos);
private static void closeQuietly(Closeable close) {if(close != null) {try {close.close();} catch (IOException e) {e.printStackTrace();}}
}//2.jdk7 中引入的 try-with-resource語句try(放申請資源的語句){}catch() {}// 一旦資源的申請放在try-with-resource語句的()中,那么資源會保證一定自動被釋放
##五、字節流文件復制
###1. 讀取單個字節
public class Copy {public static void main(String[] args) {long s = System.currentTimeMillis();//定義兩個流的對象變量FileInputStream fis = null;FileOutputStream fos = null;try{//建立兩個流的對象,綁定數據源和數據目的fis = new FileInputStream("D:\\test.mp3"); //8,003,733 字節fos = new FileOutputStream("d:\\test.mp3");//字節輸入流,讀取1個字節,輸出流寫1個字節int len = 0 ;while((len = fis.read())!=-1){fos.write(len);}}catch(IOException e){System.out.println(e);throw new RuntimeException("文件復制失敗");}finally{try{if(fos!=null)fos.close();}catch(IOException e){throw new RuntimeException("釋放資源失敗");}finally{try{if(fis!=null)fis.close();}catch(IOException e){throw new RuntimeException("釋放資源失敗");}}}long e = System.currentTimeMillis();System.out.println(e-s);}
}
//耗時:61817
###2. 讀取字節數組
public class Copy_1 {public static void main(String[] args) {long s = System.currentTimeMillis();FileInputStream fis = null;FileOutputStream fos = null;try{fis = new FileInputStream("D:\\test.mp3");fos = new FileOutputStream("E:\\test.mp3");//定義字節數組,緩沖byte[] bytes = new byte[1024*10];//讀取數組,寫入數組int len = 0 ;while((len = fis.read(bytes))!=-1){fos.write(bytes, 0, len);}}catch(IOException e){System.out.println(e);throw new RuntimeException("文件復制失敗");}finally{try{if(fos!=null)fos.close();}catch(IOException e){throw new RuntimeException("釋放資源失敗");}finally{try{if(fis!=null)fis.close();}catch(IOException e){throw new RuntimeException("釋放資源失敗");}}}long e = System.currentTimeMillis();System.out.println(e-s);}
}
//耗時:41
##六、字符輸出流
###1. 概述
java.io.Writer 所有字符輸出流的超類。寫文件,寫 文本文件
###2. 方法介紹
void write(int c):寫入單個字符
void write(String str) :寫入字符串
void write(String str, int off, int len):寫入字符串的某一部分
void write(char[] cbuf):寫入字符數組
abstract void write(char[] cbuf, int off, int len) :寫入字符數組的某一部分
###3. FileWriter 類
Writer 類是抽象類,找到子類對象 FileWriter
構造方法:參數也是 File 類型對象 和 String 文件名
字符輸出流,寫數據的時候,必須要運行一個功能,刷新功能:flush()
public class WriterDemo {public static void main(String[] args) throws IOException{FileWriter fw = new FileWriter("c:\\1.txt");//寫1個字符fw.write(100);fw.flush();//寫1個字符數組char[] c = {'a','b','c','d','e'};fw.write(c);fw.flush();//寫字符數組一部分fw.write(c, 2, 2);fw.flush();//寫如字符串fw.write("hello");fw.flush();fw.close();}
}
##七、字符輸入流
###1. 概述
java.io.Reader,字符輸入流讀取文本文件,所有字符輸入流的超類,專門讀取文本文件
###2. 方法介紹
int read(): 讀取單個字符
int read(char[] cbuf):將字符讀入數組
abstract int read(char[] cbuf, int off, int len) :將字符讀入數組的某一部分
沒有讀取字符串的方法
###3. FileReader 類
Reader類 是抽象類,找到子類對象 FileReader
構造方法:寫入的數據目的。綁定數據源。參數也是 File 類型對象 和 String 文件名
public class ReaderDemo {public static void main(String[] args) throws IOException{FileReader fr = new FileReader("c:\\1.txt");//讀字符/*int len = 0 ;while((len = fr.read())!=-1){System.out.print((char)len);}*///讀數組char[] ch = new char[1024];int len = 0 ;while((len = fr.read(ch))!=-1){System.out.print(new String(ch,0,len)); //轉字符串}fr.close();}
}
###4. flush 方法和 close 方法區別
flush()方法:用來刷新緩沖區的,刷新后可以再次寫出,只有字符流才需要刷新
close()方法:用來關閉流釋放資源的的,如果是帶緩沖區的流對象的close()方法,不但會關閉流,還會再關閉流之前刷新緩沖區,關閉后不能再寫出
##八、字符流復制文本文件
字符流復制文本文件,必須是文本文件
字符流查詢本機默認的編碼表,簡體中文GBK
FileReader 讀取數據源
FileWriter 寫入到數據目的
//讀取字符數組public class Copy_2 {public static void main(String[] args) {FileReader fr = null;FileWriter fw = null;try{fr = new FileReader("c:\\1.txt");fw = new FileWriter("d:\\1.txt");char[] cbuf = new char[1024];int len = 0 ;while(( len = fr.read(cbuf))!=-1){fw.write(cbuf, 0, len);fw.flush();}}catch(IOException ex){System.out.println(ex);throw new RuntimeException("復制失敗");}finally{try{if(fw!=null)fw.close();}catch(IOException ex){throw new RuntimeException("釋放資源失敗");}finally{try{if(fr!=null)fr.close();}catch(IOException ex){throw new RuntimeException("釋放資源失敗");}}}}
}