1. 程式人生 > >Java中的IO流詳細介紹

Java中的IO流詳細介紹

總結的很粗糙,以後時間富裕了好好修改一下。

1:Java語言定義了許多類專門負責各種方式的輸入或者輸出,這些類都被放在java.io包中。其中,

所有輸入流類都是抽象類InputStream(位元組輸入流),或者抽象類Reader(字元輸入流)的子類;

而所有輸出流都是抽象類OutputStream(位元組輸出流)或者Writer(字元輸出流)的子類。

【首先需要明白的是:流是幹什麼的???(為了永久性的儲存資料)

  根據資料流向的不同分為輸入流和輸出流;

  根據處理資料型別的不同分為字元流和位元組流;

【然後需要明白的是輸入模式和輸出模式是誰流向誰:

InputStream(位元組輸入流)和Reader(字元輸入流)通俗的理解都是讀(read)的。

OutputStream(位元組輸出流)和Writer(字元輸出流)通俗的理解都是寫(writer)的。

最後下面搞清楚各種流的型別的該怎麼用,誰包含誰,理清思路。

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

3:java中的字元是Unicode編碼的,是雙位元組的。InputStream是用來處理位元組的,在處理字元文字時很不方便。Java為字元文字的輸入提供了專門的一套類Reader。Reader類是字元輸入流的抽象類,所有字元輸入流的實現都是它的子類。

4:輸出流OutputStream類是位元組輸入流的抽象類,此抽象類表示輸出位元組流的所有類的超類。

5:Writer類是字元輸出流的抽象類,所有字元輸出類的實現都是它的子類。

6:File類是IO包中唯一代表磁碟檔案本身的物件。通過File來建立,刪除,重新命名檔案。File類物件的主要作用就是用來獲取文字本身的一些資訊。如文字的所在的目錄,檔案的長度,讀寫許可權等等。(有的需要記憶,比如isFile(),isDirectory(),exits();有的瞭解即可。使用的時候檢視API)

詳細如下:

File類(File類的概述和構造方法)

A:File類的概述

  File更應該叫做一個路徑

  檔案路徑或者資料夾路徑

  路徑分為絕對路徑和相對路徑

    絕對路徑是一個固定的路徑,從碟符開始

    相對路徑相對於某個位置,在eclipse下是指當前專案下,在dos下

  檢視API指的是當前路徑

  檔案和目錄路徑名的抽象表示形式

B:構造方法

  File(String pathname):根據一個路徑得到File物件

  File(String parent, String child):根據一個目錄和一個子檔案/目錄得到File物件

  File(File parent, String child):根據一個父File物件和一個子檔案/目錄得到File物件

File類(File類的建立功能)

  A:建立功能

    public boolean createNewFile():建立檔案 如果存在這樣的檔案,就不建立了

    public boolean mkdir():建立資料夾 如果存在這樣的資料夾,就不建立了

    public boolean mkdirs():建立資料夾,如果父資料夾不存在,會幫你創建出來

(使用createNewFile()檔案建立的時候不加.txt或者其他字尾也是檔案,不是資料夾;使用mkdir()建立資料夾的時候,如果起的名字是比如aaa.txt也是資料夾不是檔案;)

注意事項:

如果你建立檔案或者資料夾忘了寫碟符路徑,那麼,預設在專案路徑下。

File類(File類的重新命名和刪除功能)

  A:重新命名和刪除功能

    public boolean renameTo(File dest):把檔案重新命名為指定的檔案路徑

    public boolean delete():刪除檔案或者資料夾

  B:重新命名注意事項

    如果路徑名相同,就是改名。

    如果路徑名不同,就是改名並剪下。

  C:刪除注意事項:

    Java中的刪除不走回收站。

    要刪除一個資料夾,請注意該資料夾內不能包含檔案或者資料夾

File類(File類的判斷功能)

  A:判斷功能

    public boolean isDirectory():判斷是否是目錄

    public boolean isFile():判斷是否是檔案

    public boolean exists():判斷是否存在

    public boolean canRead():判斷是否可讀

    public boolean canWrite():判斷是否可寫

    public boolean isHidden():判斷是否隱藏

File類(File類的獲取功能)

  A:獲取功能

    public String getAbsolutePath():獲取絕對路徑

    public String getPath():獲取路徑

    public String getName():獲取名稱

    public long length():獲取長度。位元組數

    public long lastModified():獲取最後一次的修改時間,毫秒值

    public String[] list():獲取指定目錄下的所有檔案或者資料夾的名稱陣列

    public File[] listFiles():獲取指定目錄下的所有檔案或者資料夾的File陣列

File類(檔名稱過濾器的概述及使用)

  A:檔名稱過濾器的概述

    public String[] list(FilenameFilter filter)

    public File[] listFiles(FileFilter filter)

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.File;
 4 
 5 public class Test {
 6 
 7     public static void main(String[] args) throws Exception{
 8         // TODO Auto-generated method stub
 9         File file=new File("aa.txt");//檔案預設就建立在你建立的專案下面,重新整理即可看到
10         System.out.println(file.exists());//判斷檔案是否存在
11         file.createNewFile();//建立檔案,不是資料夾
12         System.out.println(file.exists());//再次判斷是否存在
13         System.out.println(file.getName());//獲取檔案的名字
14         System.out.println(file.getAbsolutePath());//獲取檔案的絕對路徑
15         System.out.println(file.getPath());//獲取檔案的相對路徑
16         System.out.println(file.getParent());//獲取檔案的父路徑
17         System.out.println(file.canRead());//檔案是否可讀
18         System.out.println(file.canWrite());//檔案是否可寫
19         System.out.println(file.length());//檔案的長度
20         System.out.println(file.lastModified());//檔案最後一次修改的時間
21         System.out.println(file.isDirectory());//判斷檔案是否是一個目錄
22         System.out.println(file.isHidden());//檔案是否隱藏
23         System.out.println(file.isFile());//判斷檔案是否存在
24     }
25 
26 }

複製程式碼

  public String[] list():獲取指定目錄下的所有檔案或者資料夾的名稱陣列

  public File[] listFiles():獲取指定目錄下的所有檔案或者資料夾的File陣列

list()獲取某個目錄下所有的檔案或者資料夾:

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.File;
 4 
 5 public class FileTest {
 6 
 7     public static void main(String[] args){
 8         File file=new File("D:/");//指定檔案目錄
 9         String[] str=file.list();//獲取指定目錄下的所有檔案或者資料夾的名稱陣列
10         for(String s : str){//加強for迴圈遍歷輸出
11             System.out.println(s);
12         }
13         
14     }
15 }

複製程式碼

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.File;
 4 
 5 public class FileTest {
 6 
 7     public static void main(String[] args){
 8         File file=new File("D:/");//指定檔案路徑
 9         File[] f=file.listFiles();//獲取指定目錄下的所有檔案或者資料夾的File陣列
10         for(File fi : f){//加強for迴圈遍歷輸出
11             System.out.println(fi);
12         }
13         
14     }
15 }

複製程式碼

案例演示:

獲取某種格式的檔案比如獲取某種字尾的圖片,並輸出檔名:

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.File;
 4 
 5 public class FileTest {
 6 
 7     public static void main(String[] args){
 8         File file=new File("C:\\Users\\biehongli\\Pictures\\xuniji");
 9         String[] str=file.list();
10         
11         for(String s : str){
12             if(s.endsWith(".jpg") || s.endsWith(".png")){//如果字尾是這種格式的就輸出
13                 System.out.println(s);
14             }
15         }
16         
17         
18     }
19 }

複製程式碼

下面演示獲取資料夾下面子目錄裡面的檔案獲取(並沒有完全獲取子目錄的子目錄等等,僅僅獲取了子一級目錄):

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.File;
 4 
 5 public class FileTest {
 6 
 7     public static void main(String[] args){
 8         File file=new File("C:\\Users\\biehongli\\Pictures\\Camera Roll");
 9         
10         File[] f=file.listFiles();
11         
12         for(File fi : f){
13             if(fi.isDirectory()){//判斷如果是一個目錄
14                 String[] s=fi.list();
15                 for(String str : s){
16                     if(str.endsWith(".jpg")){
17                         System.out.println(str);
18                     }
19                 }
20             }
21         }
22     }
23 }

複製程式碼

A:檔名稱過濾器的概述

    public String[] list(FilenameFilter filter)

    public File[] listFiles(FileFilter filter)

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.File;
 4 import java.io.FilenameFilter;
 5 
 6 public class FileTest {
 7 
 8     public static void main(String[] args){
 9         File file=new File("C:\\Users\\biehongli\\Pictures\\Camera Roll");
10         
11         String[] str=file.list(new FilenameFilter() {//過濾器,匿名內部類
12             
13             @Override
14             public boolean accept(File dir, String name) {
15                 // TODO Auto-generated method stub
16                 //System.out.println(dir);//獲取檔案的路徑
17                 //System.out.println(name);//獲取檔案的名字
18                 File f=new File(dir,name);
19                 return f.isFile() && f.getName().endsWith(".jpg");
20             }
21         });
22         for(String s : str){
23             System.out.println(s);
24         }
25         
26     }
27 }

複製程式碼

7:下面以一些位元組輸入輸出流具體的案例操作(操作的時候認清自己使用的是位元組流還是字元流):

注意:read()方法讀取的是一個位元組,為什麼返回是int,而不是byte

位元組輸入流可以操作任意型別的檔案,比如圖片音訊等,這些檔案底層都是以二進位制形式的儲存的,如果每次讀取都返回byte,有可能在讀到中間的時候遇到111111111;那麼這11111111是byte型別的-1,我們的程式是遇到-1就會停止不讀了,後面的資料就讀不到了,所以在讀取的時候用int型別接收,如果11111111會在其前面補上;24個0湊足4個位元組,那麼byte型別的-1就變成int型別的255了這樣可以保證整個資料讀完,而結束標記的-1就是int型別

FileInputStream的單個位元組讀取:

FileOutputStream的單個位元組寫入:

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 
 6 public class FileTest {
 7 
 8     public static void main(String[] args) throws Exception{
 9         FileInputStream fis=new FileInputStream("aaa.txt");
10         FileOutputStream fos=new FileOutputStream("bbb.txt",true);
11         //FileOutputStream()後面加true指檔案後面可追加
12         
13         int a=fis.read();//read()一次讀取一個位元組
14         System.out.println(a);//讀取的一個位元組輸出
15         
16         fos.write(101);//write()一次寫一個位元組
17         fis.close();//一定記得關閉流,養成好習慣
18         fos.close();
19     }
20 }

複製程式碼

FileInputStream和FileOutputStream進行拷貝文字或者圖片或者歌曲:

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 
 6 public class FileTest {
 7 
 8     public static void main(String[] args) throws Exception{
 9         FileInputStream fis=new FileInputStream("aaa.txt");
10         FileOutputStream fos=new FileOutputStream("bbb.txt");
11         //如果沒有bbb.txt,會創建出一個
12         
13         int b;
14         while((b=fis.read())!=-1){
15             fos.write(b);
16         }
17         fis.close();
18         fos.close();
19     }
20 }

複製程式碼

FileInputStream和FileOutputStream定義小陣列進行讀寫操作:

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 
 6 public class FileTest {
 7 
 8     public static void main(String[] args) throws Exception{
 9         FileInputStream fis = new FileInputStream("aaa.txt");
10         FileOutputStream fos = new FileOutputStream("bbb.txt");
11         int len;
12         byte[] arr = new byte[1024 * 8];//自定義位元組陣列
13         
14         while((len = fis.read(arr)) != -1) {
15             //fos.write(arr);
16             fos.write(arr, 0, len);//寫出位元組陣列寫出有效個位元組個數
17         }
18         //IO流(定義小陣列)
19         //write(byte[] b)
20         //write(byte[] b, int off, int len)寫出有效的位元組個數
21 
22         fis.close();
23         fos.close();
24     }
25 }

複製程式碼

 IO流(BufferedInputStream和BufferOutputStream拷貝)

* A:緩衝思想

  * 位元組流一次讀寫一個數組的速度明顯比一次讀寫一個位元組的速度快很多,

  * 這是加入了陣列這樣的緩衝區效果,java本身在設計的時候,

  * 也考慮到了這樣的設計思想,所以提供了位元組緩衝區流

* B.BufferedInputStream

  * BufferedInputStream內建了一個緩衝區(陣列)

  * 從BufferedInputStream中讀取一個位元組時

  * BufferedInputStream會一次性從檔案中讀取8192個, 存在緩衝區中, 返回給程式一個

  * 程式再次讀取時, 就不用找檔案了, 直接從緩衝區中獲取

  * 直到緩衝區中所有的都被使用過, 才重新從檔案中讀取8192個

* C.BufferedOutputStream

  * BufferedOutputStream也內建了一個緩衝區(陣列)

  * 程式向流中寫出位元組時, 不會直接寫到檔案, 先寫到緩衝區中

  * 直到緩衝區寫滿, BufferedOutputStream才會把緩衝區中的資料一次性寫到檔案裡

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.BufferedInputStream;
 4 import java.io.BufferedOutputStream;
 5 import java.io.FileInputStream;
 6 import java.io.FileOutputStream;
 7 
 8 public class FileTest {
 9 
10     public static void main(String[] args) throws Exception{
11         FileInputStream fis = new FileInputStream("aaa.txt");
12         FileOutputStream fos = new FileOutputStream("bbb.txt");
13         
14         BufferedInputStream bis=new BufferedInputStream(fis);
15         //使用裝飾模式,把fis裝飾進去bis中。使用緩衝讀取速度變快
16         BufferedOutputStream bos=new BufferedOutputStream(fos);
17         
18         int b;
19         while((b=bis.read())!=-1){
20             bos.write(b);
21         }
22         bis.close();
23         bos.close();
24     }
25 }

複製程式碼

 面試題小陣列的讀寫和帶Buffered的讀取哪個更快?

  * 定義小陣列如果是8192個位元組大小和Buffered比較的話

  * 定義小陣列會略勝一籌,因為讀和寫操作的是同一個陣列

  * 而Buffered操作的是兩個陣列

IO流(flush和close方法的區別)

flush()方法: 用來重新整理緩衝區的,重新整理後可以再次寫出(位元組緩衝流內建緩衝區,如果沒有讀取出來,可以使用flush()重新整理來)

close()方法:用來關閉流釋放資源的的,如果是帶緩衝區的流物件的close()方法,不但會關閉流,還會再關閉流之前重新整理緩衝區,關閉後不能再寫出

8:字元流FileReader和FileWriter

字元流是什麼

  * 字元流是可以直接讀寫字元的IO流

  * 字元流讀取字元, 就要先讀取到位元組資料, 然後轉為字元. 如果要寫出字元, 需要把字元轉為位元組再寫出.    

IO流(什麼情況下使用字元流)

* 字元流也可以拷貝文字檔案, 但不推薦使用. 因為讀取時會把位元組轉為字元, 寫出時還要把字元轉回位元組.

* 程式需要讀取一段文字, 或者需要寫出一段文字的時候可以使用字元流

* 讀取的時候是按照字元的大小讀取的,不會出現半個中文

* 寫出的時候可以直接將字串寫出,不用轉換為位元組陣列

IO流(字元流是否可以拷貝非純文字的檔案)

* 不可以拷貝非純文字的檔案

* 因為在讀的時候會將位元組轉換為字元,在轉換過程中,可能找不到對應的字元,就會用?代替,寫出的時候會將字元轉換成位元組寫出去

* 如果是?,直接寫出,這樣寫出之後的檔案就亂了,看不了了

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.FileReader;
 4 import java.io.FileWriter;
 5 
 6 public class FileTest {
 7 
 8     public static void main(String[] args) throws Exception{
 9         //FileReader類的read()方法可以按照字元大小讀取
10         FileReader fr=new FileReader("aaa.txt");
11         int b;
12         while((b=fr.read())!=-1){
13             System.out.println((char)b);//int型別轉為字元型
14         }
15         fr.close();
16         
17         //FileWriter類的write()方法可以自動把字元轉為位元組寫出
18         FileWriter fw = new FileWriter("aaa.txt",true);
19         fw.write("aaa");
20         fw.close();
21         
22         //字元流的拷貝
23         FileReader fr2 = new FileReader("aaa.txt");
24         FileWriter fw2 = new FileWriter("bbb.txt");
25         
26         int ch;
27         while((ch = fr2.read()) != -1) {
28             fw2.write(ch);
29         }
30 
31         fr2.close();
32         fw2.close();
33     }
34 }

複製程式碼

複製程式碼

 1 package com.ningmeng;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.FileReader;
 6 import java.io.FileWriter;
 7 
 8 public class FileTest {
 9 
10     public static void main(String[] args) throws Exception{
11         BufferedReader br=new BufferedReader(new FileReader("aaa.txt"));
12         BufferedWriter bw=new BufferedWriter(new FileWriter("bbb.txt"));
13         //BufferedReader和BufferedWriter的使用:
14         int b;
15         while((b=br.read())!=-1){
16             bw.write((char)b);
17         }
18         br.close();
19         bw.close();
20     }
21 }

複製程式碼

 先寫到這裡吧,內容比較多,以後有時間再總結,也方便自己腦補