Day12 JavaSE IO原理及流的引入(上)

JavaSE IO原理及流的引入(上)

  • IO流用來處理設備之間的數據傳輸。

  • Java中,對於數據的輸入/輸出操作以“流(Stream)”的方式進行。

  • java.io包下提供了各種“流”類和接口,用來獲取不同種類的數據,並通過標準的方法輸入或輸出數據。

Java IO原理

輸入input: 讀取外部數據(磁盤、光盤等存儲設備的數據)到程序內存中。

**輸出output:**將程序(內存)數據輸出到磁盤、光盤等存儲設備中

流的分類

按照操作數據單位不同分爲:字節流(8bit),字符流(16bit)

按照數據流的流向不同分爲:輸入流、輸出流

按照流的角色不同分爲:結點流、處理流

抽象基類 字節流 字符流
輸入流 InputStream Reader
輸出流 OutputStream Writer

1 文件流

1.1 文件字節流

  • 文件字節輸入流

    FileInputStream in = new FileInputStream("file");

    重點關注int read(byte[] b)的使用

  • 文件字節輸出流

    FileOutputStream out = new FileOutputStream("file")

    重點關注out.write(str.getBytes())out.flush()的使用

注意:字節流使用完畢後一定要關閉

文件輸入輸出流案例:

package com.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo02 {
    public static void main(String[] args) {
        testFileInputStream();
        testFileOutputStream();

    }
    //文件字節輸入流
    public static void testFileInputStream(){
        try {
            FileInputStream in = new FileInputStream("/Users/demut/Documents/File/aaa.txt");

            byte[] b = new byte[100]; //設置一個byte數組接受讀取的文件內容
            int len = 0;//設置一個讀取數據的長度

//            in.read(b);//讀取字符到b數組,返回讀取到的字符個數,如果是文件結尾返回-1
            while((len = in.read(b)) != -1){
                System.out.println(new String(b,0,len));
                //new String(b,0,len)表示從0開始讀取,總共轉換len個字節
            }
            in.close();//流在使用完畢之後一定要關閉
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //文件字節輸出流
    public static void testFileOutputStream(){
        try {
            FileOutputStream out = new FileOutputStream("/Users/demut/Documents/File/aaa.txt");
            String str = "aaaaaabbbbbbbccc";
            out.write(str.getBytes());//把數據寫入內存
            out.flush(); //將內存中的數據刷寫到硬盤上

            out.close();//關閉流
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

複製文件到指定文件/文件夾案例:

package com.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//複製文件到指定文件夾下
public class Demo03 {
    public static void main(String[] args) {
        //將aaa.txt中內容寫入到tt1.txt文件中
        copyFile("/Users/demut/Documents/File/aaa.txt","/Users/demut/Documents/File/tt1.txt");
    }

    public static void copyFile(String inPath, String outPath){
        try {
            FileInputStream in = new FileInputStream(inPath);
            FileOutputStream out = new FileOutputStream(outPath);

            byte[] b = new byte[100];

            int len = 0;
            while ((len = in.read(b)) != -1){
                out.write(b, 0, len); //b表示緩衝數組,0表示從數組的位置開始寫,len表示獲取的數組總長度
            }
            out.flush();
            out.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

結果展示:(寫入成功!)

運行前:
運行前
運行後:
運行前

注意: 文件字節流非常通用,可以用來操作字符的文檔,還可以操作任何的其他類型文件(圖片,壓縮包等),因爲字節流直接使用二進制。

1.2 文件字符流

  • 文件字符輸入流

    讀取文件操作步驟:

    1. 建立一個流對象,將已存在的一個文件加載進流。

      FileReader fr = FileReader("Test.txt");

    2. 創建一個臨時存放數據的數組。

      char[] ch = new char[1024];

    3. 調用流對象的讀取方法將流中的數據讀入到數組中。

      fr.read(ch)

  • 文件字符輸出流

    數據寫入文件操作步驟:

    1. 建立一個流對象,將已存在/不存在的一個文件加載進流。

      FileWriter fw = FileWriter("Test.txt");

    2. 將讀取到的字符數組/字符串/數字寫入內存中。

      fw.write(text);

    3. 把內存中數據刷到硬盤中,即寫入文件。

      fw.flush();

注意: 無論是輸入流/輸出流,使用完畢一定要關閉流

文件字符輸入&&輸出流案例:

package com.io;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test4 {
    public static void main(String[] args) {
        File file = new File("/Users/demut/Documents/File/ttt.txt");
        testFileReader(file.toString()); //讀取原文件中字符串
        testFileWriter("HelloWorld",file.toString()); //寫入新的字符串到文件中
        testFileReader(file.toString()); //讀取更改後文件內部的字符串
    }

    /**
     * 文件字符輸入流
     * @param inPath 讀取的文件
     */
    public static void testFileReader(String inPath){
        try {
            FileReader fr = new FileReader(inPath);//創建文件字符輸入流的對象

            char[] c = new char[10]; //創建臨時存放數據的數組-->一次最多存放10個

            int len = 0; //定義一個輸入流的讀取長度
            while ((len = fr.read(c)) != -1){
                System.out.println(new String(c, 0, len));
            }
            fr.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  
    /**
     * 文件字符輸出流FileWriter
     * @param text 輸出的內容
     * @param outPath   輸出的文件
     */
    public static void testFileWriter(String text, String outPath){
        try {
            FileWriter fw = new FileWriter(outPath);

            fw.write(text); //寫到內存中
            fw.flush(); //把內存數據刷到硬盤中
            fw.close(); //關閉流
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

運行結果:

更改前:
更改前
更改後:
更改後

使用字符流拷貝文件到指定文件案例:

package com.io;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test4 {
    public static void main(String[] args) {
              copyFile("/Users/demut/Documents/File/ttt.txt",
                       "/Users/demut/Documents/File/aaa/ttt1.txt");
    }
  
    /**
     *  字符流完成拷貝文件,字符流只適合操作內容是字符的文件
     * @param inPath
     * @param outPath
     */
    public static void copyFile(String inPath, String outPath){
        try {
            FileReader fr = new FileReader(inPath);
            FileWriter fw = new FileWriter(outPath);

            char[] c = new char[1024];

            int len = 0;

            while ((len = fr.read(c)) != -1){ //讀取數據
                fw.write(c,0,len); //寫入數據到內存中
            }
            fw.flush(); //內存數據刷新到硬盤

            fw.close();
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

運行結果:

運行前:
文件複製前
運行後:
文件複製後

注意:

  • 字符流只適合操作內容是字符的文件!
  • 在寫入一個文件時,如果目錄下有同名文件將被覆蓋。
  • 在讀取文件時,必須保證文件存在,否則會異常。

2 緩衝流(基於內存的操作)

我們之前提到的文件流:FileInputStream, FileOutputStream,FileReader, FileWrite

這些都是計算機與硬盤之間發生的io操作,基於硬盤的讀寫相對不較慢,這個操作的速度收到硬盤的讀寫速度制約,爲了能夠提高讀寫速度,一定程度上繞過硬盤的限制,java提供了緩衝流來實現。

爲了提高數據讀寫的速度,JavaAPI提供了帶緩衝功能的流類,在使用這些流類時,會創建一個內部緩衝區數組。

緩衝流就是先把數據緩衝到內存中,在內存中去做io操作,基於內存的io操作比基於硬盤的io操作快75000多倍。

2.1 緩衝字節流

使用與文件字符流使用相像,但是聲明過程爲以下:

  • 緩衝字節輸入流:

    FileInputStream in = new FileInputStream("...");

    BufferedInputStream br = new BufferedInputStream(in);

  • 緩衝字節輸出流

    FileOutputStream out = new FileOutputStream("...");

    BufferedOutputStream bo = new BufferedOutputStream(out)

案例展示:(本案例展示緩衝字節輸入、輸出流及拷貝文件的操作)

package com.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test5 {
    public static void main(String[] args) throws Exception {
        testBufferedInputStream();
        testBufferedOutputStream();
        copyFile();
    }

    /**
     * 緩衝字節輸入流
     * @throws Exception
     */
    public static void testBufferedInputStream() throws Exception{

        //文件字節輸入流對象
        FileInputStream in = new FileInputStream("/Users/demut/JAVASE Project" +
                                                    "/JavaSE/基礎語法/src/com/io/aaa.txt");

        //把文件字節輸入流放到緩衝字節輸入流對象
        BufferedInputStream br = new BufferedInputStream(in);

        byte[] b = new byte[10];

        int len = 0;

        while ((len = br.read(b)) != -1){
            System.out.println(new String(b,0,len));//將比特數組轉換爲字符串
        }

        //關閉流的時候順序要求:後開的流先關閉
        br.close();
        in.close();
    }

    /**
     * 緩衝字節輸出流
     * @throws Exception
     */
    public static void testBufferedOutputStream() throws Exception{

        //創建字節輸出流對象
        FileOutputStream out = new FileOutputStream("/Users/demut/JAVASE Project" +
                                                    "/JavaSE/基礎語法/src/com/io/aaa.txt");

        //把字節輸出流對象放到緩衝字節輸出流中
        BufferedOutputStream bo = new BufferedOutputStream(out);

        String str = "Hello World";

        bo.write(str.getBytes()); //寫入內存中

        bo.flush(); //內存中數據刷到硬盤上

        bo.close(); //關閉流
        out.close(); //關閉流
    }

    /**
     * 拷貝文件
     * @throws Exception
     */
    public static void copyFile() throws Exception{

        //緩衝輸入流
        BufferedInputStream br = new BufferedInputStream(new FileInputStream("/Users/demut/JAVASE Project" +
                                                                    "/JavaSE/基礎語法/src/com/io/aaa.txt"));
        //緩衝輸出流
        BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("/Users/demut/JAVASE Project" +
                                                                    "/JavaSE/基礎語法/src/com/io/bbb.txt"));
        byte[] b = new byte[1024];

        int len = 0; //len接受讀取到的數據的長度,直到讀取到最後(返回-1)

        while ((len = br.read(b)) != -1){
            bo.write(b,0,len); //數據寫入內存中
        }
        bo.flush(); //數據從內存刷新到硬盤中

        bo.close();
        br.close();
    }
}

結果展示:(僅展示拷貝文件結果)

程序運行前:
拷貝前
程序運行後:
拷貝後

2.2 緩衝字符流

同樣與上述使用十分相似,注意聲明語句如下:

  • 緩衝字符輸入流:

    FileReader fr = new FileReader("...");

    BufferedReader br = new BufferedReader(fr);

  • 緩衝字節輸出流

    FileWriter fw = new FileWriter("...");

    BufferedWriter bw = new BufferedWriter(fw)

案例展示:(本案例展示緩衝字符輸入、輸出流及拷貝文件的操作)

package com.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

/**
 * 緩衝字符流
 */
public class Test6 {
    public static void main(String[] args) throws Exception{
        //testBufferedReader();
        //testBufferedWriter();
        copyFile();
    }

    /**
     * 緩衝字符輸入流
     * BufferedReader
     * @throws Exception
     */
    public static void testBufferedReader() throws Exception{
        FileReader fr = new FileReader("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/aaa.txt");

        BufferedReader br = new BufferedReader(fr);

        char[] c = new char[100];

        int len = 0;
        while ((len = br.read(c))!=-1){
            System.out.println(new String(c,0,len));
        }
        br.close();
        fr.close();
    }

    /**
     * 緩衝字符輸出流
     * BufferedWriter
     * @throws Exception
     */
    public static void testBufferedWriter() throws Exception{
        FileWriter fw = new FileWriter("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/bbb.txt");

        BufferedWriter bw = new BufferedWriter(fw);
        String str = "JeverDemut";

        bw.write(str); //寫入內存
        bw.flush(); //刷入硬盤

        bw.close();
        fw.close();
    }

    /**
     * 使用緩衝字符流拷貝文件
     * @throws Exception
     */
    public static void copyFile() throws Exception{
        BufferedReader br = new BufferedReader(new FileReader("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/bbb.txt"));

        BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/ccc.txt"));

        char[] c = new char[100];
        int len  = 0;
        while ((len = br.read(c))!=-1){
            bw.write(c,0,len);
        }
        bw.flush();

        bw.close();
        br.close();
    }
}

結果展示:(僅展示拷貝文件結果)

程序運行前:
複製前
程序運行後:
複製後

注意:緩衝流是把數據緩衝到內存中。

**JavaSE IO原理及流的引入(下)**重點介紹以下流:

轉換流、打印流(瞭解)、數據流(瞭解)、對象流 —涉及序列化、反序列化、隨機存取文件流

寫在最後

My darling,我和FF99FF時刻在想你!

To Dottie!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章