Java基礎進階 緩衝流、轉換流、序列化流、Files類 D190406

Java基礎進階 緩衝流、轉換流、序列化流、Files類

01.第一章:緩衝流_概述

1).我們之前使用字節/字符的基本流時,使用數組的方式比較快。
2).基於這種原因,Java類庫中提供了一種“緩衝流”類,它們內部自動帶了“數組”,而且自動向數組中讀、寫數據,
這種流:叫:緩衝流。由於它內部帶了數組,所以可以大大提高程序的讀寫效率。它們內部的“數組”就叫:緩存區。
3).緩衝流的類結構:
A).字節流:
1).輸出流:OutputStream(三種輸出的方法)
|–FileOutputStream(基本流)
|–FilterOutputStream(不學)
|–BufferedOutputStream(緩衝流–今天學)
2).輸入流:InputStream(兩種讀取的方法)
|–FileInputStream(基本流)
|–FilterInputStream(不學)
|–BufferedInputStream("緩衝流–今天學)
B).字符流:
1).輸出流:Writer(五種輸出的方法)
|–OutputStreamWriter(轉換流–今天學)
|–FileWriter(基本流)
|–BufferedWriter(緩衝流–今天學)
2).輸入流:Reader(兩種讀取的方法)
|–InputStreamReader(轉換流–今天學)
|–FileReader(基本流)
|–BufferedReader(緩衝流–今天學)
注意:
1).緩衝流的前綴都帶:Buffered
2).緩衝流基本沒有特有方法,都是從父類繼承/重寫的。只是他們內部的工作方式不同,可以提供”緩存區”
來提高程序的讀寫效率。

02.第一章:緩衝流_字節緩衝流

1).輸出流:BufferedOutputStream
2).輸入流:BufferedInputStream
無特有方法,跟基本流一樣操作,就是:效率高。
在這裏插入圖片描述

public class Demo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
//        copy1();//3509 毫秒(緩衝流--一次讀寫一個字節)
//        copy2();//280 毫秒(緩衝流--一次讀寫一個字節數組)
//        copy3();//361061 毫秒(基本流--一次讀寫一個字節)
        copy4();//875 毫秒(基本流--一次讀寫一個字節數組)
        long end = System.currentTimeMillis();
        System.out.println("用時:" + (end - start) + " 毫秒");
    }

    private static void copy4() {
        try (FileInputStream in = new FileInputStream("d:\\視頻.itcast");
             FileOutputStream out = new FileOutputStream("d:\\視頻_copy3.itcast")
        ) {
            //一次讀寫一個字節數組
            int len = 0;
            byte[] byteArray = new byte[1024];
            while ((len = in.read(byteArray)) != -1) {
                out.write(byteArray,0,len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void copy3() {
        try (FileInputStream in = new FileInputStream("d:\\視頻.itcast");
             FileOutputStream out = new FileOutputStream("d:\\視頻_copy3.itcast")
        ) {
           //一次讀寫一個字節
           int b = 0;
            while ((b = in.read()) != -1) {
                out.write(b);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void copy2() {
        //1.構造一個輸入流
        try (BufferedInputStream bufIn = new BufferedInputStream(
						new FileInputStream("d:\\視頻.itcast"));
             BufferedOutputStream bufOut = new BufferedOutputStream(
						new FileOutputStream("d:\\視頻_copy2.itcast"))
        ) {
            //一次讀寫一個字節數組
            int len = 0;
            byte[] byteArray = new byte[1024];

            while ((len = bufIn.read(byteArray)) != -1) {
                bufOut.write(byteArray,0,len);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void copy1() {
        //1.構造一個輸入流
        try (BufferedInputStream bufIn = new BufferedInputStream(
						new FileInputStream("d:\\視頻.itcast"));
             BufferedOutputStream bufOut = new BufferedOutputStream(
						new FileOutputStream("d:\\視頻_copy1.itcast"))
        ) {
            //一次讀寫一個字節
            int b = 0;
            while ((b = bufIn.read()) != -1) {
                bufOut.write(b);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

03.第一章:緩衝流_字符緩衝流

1).輸出流:BufferedWriter
特有方法:newLine():輸出一個換行符“\r\n”;
2).輸入流:BufferedReader
特有方法:readLine():讀取一行數據。
3).示例代碼:

public class Demo {
    public static void main(String[] args) {
        //1.字符緩衝輸入流
        try (BufferedReader bufIn = new BufferedReader(
						new FileReader("d:\\demo01.txt"));
             BufferedWriter bufOut = new BufferedWriter(
						new FileWriter("d:\\demo01_copy.txt"))
        ) {
            //一次讀一行
            String row = null;
            while((row = bufIn.readLine()) != null){//注意:讀取一行,不包括換行符
                bufOut.write(row);
                bufOut.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

04.第一章:緩衝流_練習_文本排序_案例分析
在這裏插入圖片描述

05.第一章:緩衝流_練習_文本排序_案例實現

	public class Demo {
    public static void main(String[] args) {
        //1.構造一個輸入流--按行讀--字符緩衝輸入流
        try (BufferedReader bufIn = new BufferedReader(new FileReader("demo01.txt"));
             BufferedWriter bufOut = new BufferedWriter(new FileWriter("demo01_copy.txt"))
        ) {

            //一次讀寫一行
            String row = null;
            Map<Integer, String> map = new HashMap<>();

            while ((row = bufIn.readLine()) != null) {//row = 3.xxxxxx
                String id = row.substring(0, row.indexOf("."));
                String str = row.substring(row.indexOf(".") + 1);
                map.put(Integer.parseInt(id), str);
            }
            //循環寫入
            for (int i = 1; i <=9 ; i++) {
                String str = map.get(i);//xxxxx
                str = i + "." + str;//1.xxxxx
                bufOut.write(str);
                bufOut.newLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

06.第二章:轉換流_編碼引出的問題

1).如果磁盤上有一個GBK編碼的文件,我們使用程序用UTF-8編碼讀取,這樣就會產生:亂碼的現象。
2).FileWriter和FileReader不能指定編碼方式,固定用系統默認的(UTF-8)讀取,很不靈活。
3).它們的父類提供了指定編碼的方式:
Writer
|–OutputStreamWriter(轉換流)(可以指定字符集)
|–FileWriter(子類)(只能使用系統默認字符集)
Reader
|–InputStreamReader(轉換流)(可以指定字符集)
|–FileReader(子類)(只能使用系統默認字符集)

07.第二章:轉換流_轉換輸出流OutputStreamWriter的使用

public class Demo {
    public static void main(String[] args) {
        try (OutputStreamWriter osw = new OutputStreamWriter(
					new FileOutputStream("demo04.txt"),"GBK")) {
            osw.write("你好");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

08.第二章:轉換流_轉換輸入流InputStreamReader的使用

public class Demo {
    public static void main(String[] args) {
        try (InputStreamReader isr = new InputStreamReader(
					new FileInputStream("demo04.txt"),"GBK")) {
            int c = 0;
            while ((c = isr.read()) != -1) {
                System.out.println((char)c);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

09.第二章:轉換流_練習_轉換文件編碼

1).複製一個GBK的文件,新文件要求是:UTF-8編碼的。
2).代碼:

public class Demo {
    public static void main(String[] args) {
        //1.構造一個輸入流--由於要指定GBK讀取,所以使用:轉換流
        //2.構造一個輸出流,使用UTF-8編碼
        try (InputStreamReader in = new InputStreamReader(
					new FileInputStream("demo05.txt"),"GBK");
             OutputStreamWriter out = new OutputStreamWriter(
					new FileOutputStream("demo05_UTF8.txt"),"UTF-8")
        ) {
            //一次讀取一個字符
            int c = 0;
            while ((c = in.read()) != -1) {//按GBK讀取的
                out.write(c);//按UTF-8輸出
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

10.第三章:序列化_概述:

1).什麼是“序列化”:指將一個內存中的“對象”,連同“屬性值”一起存儲到文件中。
2).什麼是“反序列化”:指將之前序列化的對象,從文件中再讀取進來,並在內存中再次創建對象。

11.第三章:序列化_序列化流ObjectOutputStream類

    public class Student implements Serializable{
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

public class Demo {
    public static void main(String[] args) {
        //創建一個序列化流對象
        try (ObjectOutputStream oos = new ObjectOutputStream(
						new FileOutputStream("demo07_obj.txt"))) {
            Student stu = new Student("成龍", 17);
             //序列化對象
            oos.writeObject(stu);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

12.第三章:序列化_反序列化ObjectInputStream類

public class Demo {
    public static void main(String[] args) {
        //1.創建一個反序列化對象
            try (ObjectInputStream ois = new ObjectInputStream(
						new FileInputStream("demo07_obj.txt"))) {
                //讀取對象
                Object obj = ois.readObject();//在內存中創建一個Student對象
                //強轉
                Student stu = (Student)obj;
                System.out.println(stu);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

13.第三章:序列化_關於版本號

public class Student implements Serializable{
    public String name;
    public int age;
    private static final long serialVersionUID = 2L;
}

14.第三章:序列化_禁止屬性被序列化transient關鍵字

1).如果類中的某個屬性不希望被序列化,可以被聲明爲:transient
2).示例:

public class Student implements Serializable{
    public String name;
    public transient int age;//當序列化Student對象時,此屬性的值不會被序列化到文件中
}

15.第三章:序列化_練習_序列化集合

1).不建議一個文件中序列化多個對象。可以將多個對象存儲到一個List集合中,然後將這個集合對象序列化到文件中。
2).序列化:

public class Demo {
    public static void main(String[] args) {
        Student stu1 = new Student("成龍", 17);
        Student stu2 = new Student("甄子丹", 15);
        Student stu3 = new Student("洪金寶", 19);

        ArrayList<Student> stuList = new ArrayList<>();

        stuList.add(stu1);
        stuList.add(stu2);
        stuList.add(stu3);

        //序列化
        try (ObjectOutputStream out = new ObjectOutputStream(
						new FileOutputStream("demo10_obj.txt"))) {
              //序列化集合
		out.writeObject(stuList);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3).反序列化:

public class Demo02 {
    public static void main(String[] args) {
        try (ObjectInputStream objIn = new ObjectInputStream(
						new FileInputStream("demo10_obj.txt"))) {
	      //反序列化
            Object obj = objIn.readObject();
            List<Student> stuList = (List<Student>)obj;
	      //驗證
            for (Student stu : stuList) {
                System.out.println(stu);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

16.第四章:打印流_概述

1).打印流:
	1).字節打印流:PrintStream
	2).字符打印流:PrintWriter
2).特點:
	1).只有輸出流,沒有輸入流;
	2).可以向控制檯打印,也可以向文件中打印

17.第四章:打印流_字節打印流PrintStream類

public class Demo {
    public static void main(String[] args) {
        PrintStream ps = System.out;
        ps.println("HelloWorld!");

        //改變它的方向
        try (PrintStream ps2 = new PrintStream("demo11.txt")) {

            //將ps2賦值到System中,代替之前的out
            System.setOut(ps2);

            //再打印
            System.out.println("我愛");
            System.out.println("Java");
            System.out.println("呵呵");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

=============================================================
學習目標總結:
01.能夠使用字節緩衝流讀取數據到程序

02.能夠使用字節緩衝流寫出數據到文件
在這裏插入圖片描述

03.能夠明確字符緩衝流的作用和基本用法

04.能夠使用緩衝流的特殊功能

在這裏插入圖片描述

05.能夠闡述編碼表的意義
1).編碼表中存儲的各國的“文字”和“十進制數字”的映射關係。目的存儲這個文字時,
要存儲它對應的十進制的二進制表示方式。

	ASCII:a --> 97 --> 計算機:97的二進制
		b --> 98 --> 計算機:98的二進制

	GBK:"你" --> 50403 --> 計算機:50403的二進制

06.能夠使用轉換流讀取指定編碼的文本文件
07.能夠使用轉換流寫入指定編碼的文本文件
在這裏插入圖片描述

08.能夠使用序列化流寫出對象到文件

09.能夠使用反序列化流讀取文件到程序中
在這裏插入圖片描述

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