1. 程式人生 > >Java——IO總結1

Java——IO總結1

    對於任何程式設計語言而言,輸入輸出(Input/Output)系統都是非常核心的功能。程式執行需要資料,資料的獲取往往需要跟外部系統進行通訊,外部系統可能是檔案、資料庫、其他程式、網路、IO裝置等等。

 輸入(Input)指的是:可以讓程式從外部系統獲得資料(核心含義是“讀”,讀取外部資料)。如:

  •       讀取硬碟上的檔案內容到程式。例如:播放器開啟一個視訊檔案、word開啟一個doc檔案。

  •       讀取網路上某個位置內容到程式。

  •       讀取資料庫系統的資料到程式。

  •       讀取某些硬體系統資料到程式。例如:車載電腦讀取雷達掃描資訊到程式;溫控系統等。

輸出(Output)指的是:程式輸出資料給外部系統從而可以操作外部系統(核心含義是“寫”,將資料寫出到外部系統)。常見的應用有:

  •       將資料寫到硬碟中。例如:我們編輯完一個word文件後,將內容寫到硬碟上進行儲存。

  •       將資料寫到資料庫系統中。例如:我們註冊一個網站會員,實際就是後臺程式向資料庫中寫入一條記錄。

  •       將資料寫到某些硬體系統中。

      流是一個抽象、動態的概念,是一連串連續動態的資料集合。

      當程式需要讀取資料來源的資料時,就會通過IO流物件開啟一個通向資料來源的流,通過這個IO流物件的相關方法可以順序讀取資料來源中的資料。

一個簡單的流讀取資料:

public class Test1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("d:/x.txt"); // 內容是:abc
            StringBuilder sb = new StringBuilder();
            int temp = 0;
            //當temp等於-1時,表示已經到了檔案結尾,停止讀取
            while ((temp = fis.read()) != -1) {
                sb.append((char) temp);
            }
            System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //這種寫法,保證了即使遇到異常情況,也會關閉流物件。
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

IO流總結:

1. 按流的方向分類:

    輸入流:資料來源到程式(InputStream、Reader讀進來)。

    輸出流:程式到目的地(OutPutStream、Writer寫出去)。

2. 按流的處理資料單元分類:

    位元組流:按照位元組讀取資料(InputStream、OutputStream),命名上以Stream結尾的流一般是位元組流,如FileInputStream、FileOutputStream。

    字元流:按照字元讀取資料(Reader、Writer),命名上以Reader/Writer結尾的流一般是字元流,如FileReader、FileWriter。

3. 按流的功能分類:

    節點流:可以直接從資料來源或目的地讀寫資料,如FileInputStream、FileReader、DataInputStream等。

    處理流:不直接連線到資料來源或目的地,是”處理流的流”。通過對其他流的處理提高程式的效能,如BufferedInputStream、BufferedReader等。處理流也叫包裝流。

4. IO的四個基本抽象類:InputStream、OutputStream、Reader、Writer

5. InputStream的實現類:

    FileInputStream

    ByteArrayInutStream

    BufferedInputStream

    DataInputStream

    ObjectInputStream

6. OutputStream的實現類:

    FileOutputStream

    ByteArrayOutputStream

    BufferedOutputStream

    DataOutputStream

    ObjectOutputStream

    PrintStream

7. Reader的實現類

    FileReader

    BufferedReader

    InputStreamReader

8. Writer的實現類

    FileWriter

    BufferedWriter

    OutputStreamWriter

9. 把Java物件轉換為位元組序列的過程稱為物件的序列化。

10. 把位元組序列恢復為Java物件的過程稱為物件的反序列化。


示例

  1. 利用檔案位元組流(FileInputStream/FileOutputStream)實現檔案的複製

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileCopy {
    public static void main(String[] args) {
        //將a.txt內容拷貝到b.txt
        copyFile("d:/a.txt", "d:/b.txt"); 
    }
 
    /**
     * 將src檔案的內容拷貝到dec檔案
     * @param src 原始檔
     * @param dec 目標檔案
     */
    static void copyFile(String src, String dec) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        //為了提高效率,設定快取陣列!(讀取的位元組資料會暫存放到該位元組陣列中)
        byte[] buffer = new byte[1024];
        int temp = 0;
        try {
            fis = new FileInputStream(src);
            fos = new FileOutputStream(dec);
            //邊讀邊寫
            //temp指的是本次讀取的真實長度,temp等於-1時表示讀取結束
            while ((temp = fis.read(buffer)) != -1) {
                /*將快取陣列中的資料寫入檔案中,注意:寫入的是讀取的真實長度;
                 *如果使用fos.write(buffer)方法,那麼寫入的長度將會是1024,即快取
                 *陣列的長度*/
                fos.write(buffer, 0, temp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //兩個流需要分別關閉
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 使用檔案字元流FileReader與FileWriter實現文字檔案的複製

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileCopy2 {
    public static void main(String[] args) {
        // 寫法和使用Stream基本一樣。只不過,讀取時是讀取的字元。
        FileReader fr = null;
        FileWriter fw = null;
        int len = 0;
        try {
            fr = new FileReader("d:/a.txt");
            fw = new FileWriter("d:/d.txt");
            //為了提高效率,建立緩衝用的字元陣列
            char[] buffer = new char[1024];
            //邊讀邊寫
            while ((len = fr.read(buffer)) != -1) {
                fw.write(buffer, 0, len);
            }
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 使用緩衝位元組流BufferedInputStream和BufferedOutputStream實現檔案的高效率複製

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class TestBufferedFileCopy1 {
 
    public static void main(String[] args) {
        copyFile1("D:/電影/華語/大陸/尚學堂傳奇.mp4", "D:/電影/華語/大陸/尚學堂越
                 "+"來越傳奇.mp4");
    }
    /**緩衝位元組流實現的檔案複製的方法*/
    static void copyFile1(String src, String dec) {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        int temp = 0;
        try {
            fis = new FileInputStream(src);
            fos = new FileOutputStream(dec);
            //使用緩衝位元組流包裝檔案位元組流,增加緩衝功能,提高效率
            //快取區的大小(快取陣列的長度)預設是8192,也可以自己指定大小
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            while ((temp = bis.read()) != -1) {
                bos.write(temp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //注意:增加處理流後,注意流的關閉順序!“後開的先關閉!”
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 使用緩衝字元流BufferedReader與BufferedWriter實現文字檔案的複製

      BufferedReader/BufferedWriter增加了快取機制,大大提高了讀寫文字檔案的效率,同時,提供了更方便的按行讀取的方法:readLine(); 處理文字時,我們一般可以使用緩衝字元流。

      1. readLine()方法是BufferedReader特有的方法,可以對文字檔案進行更加方便的讀取操作。

      2. 寫入一行後要記得使用newLine()方法換行。

public class TestBufferedFileCopy2 {
    public static void main(String[] args) {
        // 注:處理文字檔案時,實際開發中可以用如下寫法,簡單高效!!
        FileReader fr = null;
        FileWriter fw = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        String tempString = "";
        try {
            fr = new FileReader("d:/a.txt");
            fw = new FileWriter("d:/d.txt");
            //使用緩衝字元流進行包裝
            br = new BufferedReader(fr);
            bw = new BufferedWriter(fw);
            //BufferedReader提供了更方便的readLine()方法,直接按行讀取文字
            //br.readLine()方法的返回值是一個字串物件,即文字中的一行內容
            while ((tempString = br.readLine()) != null) {
                //將讀取的一行字串寫入檔案中
                bw.write(tempString);
                //下次寫入之前先換行,否則會在上一行後邊繼續追加,而不是另起一行
                bw.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}