Java19-day10【标准输入输出流、字节字符打印流、对象序列化-反序列化流、serialVersionUIDtransient、Properties】
- 視頻+資料【鏈接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg? ?提取碼:zjxs】
- Java基礎--學習筆記(零起點打開java世界的大門)--博客匯總表
? ?
目? ?錄
01_集合到文件數據排序改進版
案例:集合到文件(數據排序改進版)
02_復制單級文件夾
案例:復制單級文件夾
03_復制多級文件夾
案例:復制多級文件夾
04_復制文件的異常處理
3.10、復制文件的異常處理
05_標準輸入流
4.1、標準輸入輸出流
06_標準輸出流
4.1、標準輸入輸出流
07_字節打印流
4.2、打印流
08_字符打印流
4.2、打印流
09_復制Java文件打印流改進版
案例:復制Java文件(打印流改進版)
10_對象序列化流
4.3、對象序列化流
11_對象反序列化流
4.3、對象序列化流
12_serialVersionUID&transient
4.3、對象序列化流
13_Properties作為Map集合的使用
4.4、Properties
14_Properties作為Map集合的特有方法
4.4、Properties
15_Properties和IO流相結合的方法
4.4、Properties
16_游戲次數
案例:游戲次數
01_集合到文件數據排序改進版
案例:集合到文件(數據排序改進版)
package com.itheima_07;import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet;public class TreeSetToFileDemo {public static void main(String[] args) throws IOException {// 2、創建TreeSet集合,通過比較器排序進行排序TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {//成績總分從高到低int num = s2.getSum() - s1.getSum();//次要條件int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;int num4 = num3 == 0 ? s1.getName().compareTo(s2.getName()) : num3;return num4;}});// 3、鍵盤錄入學生數據for (int i = 0; i < 5; i++) {Scanner sc = new Scanner(System.in);System.out.println("請錄入第" + (i + 1) + "個學生信息:");System.out.println("姓名:");String name = sc.nextLine();System.out.println("語文成績:");int chinese = sc.nextInt();System.out.println("數學成績:");int math = sc.nextInt();System.out.println("英語成績:");int english = sc.nextInt();// 4、創建學生對象,把鍵盤錄入的數據對應賦值給學生對象的成員變量Student s = new Student();s.setName(name);s.setChinese(chinese);s.setMath(math);s.setEnglish(english);// 5、把學生對象添加到TreeSet集合ts.add(s);}// 6、創建字符緩沖輸出流對象BufferedWriter bw = new BufferedWriter(new FileWriter("ts.txt"));// 7、遍歷集合,得到每一個學生對象for (Student s : ts) {// 8、把學生對象的數據拼接成指定格式的字符串//格式:姓名,語文成績,數學成績,英語成績StringBuilder sb = new StringBuilder();sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());// 9、調用字符緩沖輸出流對象的方法寫數據bw.write(sb.toString());bw.newLine();bw.flush();}// 10、釋放資源bw.close();} }02_復制單級文件夾
案例:復制單級文件夾
package com.itheima_08;import java.io.*;public class CopyFolderDemo {public static void main(String[] args) throws IOException {// 1:創建數據源目錄File對象,路徑是E:\\itcastFile srcFolder = new File("E:\\itcast2");// 2:獲取數據源目錄File對象的名稱(itcast)String srcFolderName = srcFolder.getName();// 3:創建目的地目錄File對象,路徑名是模塊名+itcast組成(myCharStream\\itcast)//File destFolder = new File("myCharStream", srcFolderName);File destFolder = new File(srcFolderName);// 4:判斷目的地目錄對應的File是否存在,如果不存在,就創建if (!destFolder.exists()) {destFolder.mkdir();}// 5:獲取數據源目錄下所有文件的File數組File[] listFiles = srcFolder.listFiles();// 6:遍歷File數組,得到每一個File對象,該File對象,其實就是數據源文件for (File srcFile : listFiles) {//數據源文件:E:\\itcast\\mn.jpg// 7:獲取數據源文件File對象的名稱(mn.jpg)String srcFileName = srcFile.getName();// 8:創建目的地文件File對象,路徑名是目的地目錄+mn.jpg組成(myCharStream\\itcast\\mn.jpg)File destFile = new File(destFolder, srcFileName);// 9:復制文件copyFile(srcFile, destFile);}}private static void copyFile(File srcFile, File destFile) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));byte[] bys = new byte[1024];int len;while ((len = bis.read(bys)) != -1) {bos.write(bys, 0, len);}bos.close();bis.close();} }03_復制多級文件夾
案例:復制多級文件夾
package com.itheima_08;import java.io.*;public class CopyFoldersDemo {public static void main(String[] args) throws IOException {//1、創建數據源File對象,路徑是E:\\itcastFile srcFile = new File("E:\\itcast");//2、創建目的地File對象,路徑是F:\\File destFile = new File("F:\\");//3、寫方法實現文件夾的復制,參數為數據源File對象和目的地File對象copyFolder(srcFile, destFile);}//復制文件夾private static void copyFolder(File srcFile, File destFile) throws IOException {//4、判斷數據源File是否是目錄if (srcFile.isDirectory()) {//A:在目的地下創建和數據源File名稱一樣的目錄String srcFileName = srcFile.getName();File newFolder = new File(destFile, srcFileName); //F:\\itcastif (!newFolder.exists()) {newFolder.mkdir();}//B:獲取數據源File下所有文件或者目錄的File數組File[] fileArray = srcFile.listFiles();//C:遍歷該File數組,得到每一個File對象for (File file : fileArray) {//D:把該File作為數據源File對象,遞歸調用復制文件夾的方法copyFolder(file, newFolder);}} else {//說明是文件,直接復制,用字節流File newFile = new File(destFile, srcFile.getName());copyFile(srcFile, newFile);}}//字節緩沖流復制文件private static void copyFile(File srcFile, File destFile) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));byte[] bys = new byte[1024];int len;while ((len = bis.read(bys)) != -1) {bos.write(bys, 0, len);}bos.close();bis.close();}}04_復制文件的異常處理
3.10、復制文件的異常處理
package com.itheima_09;import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;/*復制文件加入異常處理*/ public class CopyFileDemo {public static void main(String[] args) {}//JDK9的改進方案private static void method4() throws IOException {FileReader fr = new FileReader("fr.txt");FileWriter fw = new FileWriter("fw.txt");try (fr; fw) {char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}} catch (IOException e) {e.printStackTrace();}}//JDK7的改進方案private static void method3() {try (FileReader fr = new FileReader("fr.txt");FileWriter fw = new FileWriter("fw.txt");) {char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}} catch (IOException e) {e.printStackTrace();}}//try...catch...finally 方法內部處理異常 比較復雜private static void method2() {FileReader fr = null;FileWriter fw = null;try {fr = new FileReader("fr.txt");fw = new FileWriter("fw.txt");char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}} catch (IOException e) {e.printStackTrace();} finally {if (fw != null) {try {fw.close();} catch (IOException e) {e.printStackTrace();}}if (fr != null) {try {fr.close();} catch (IOException e) {e.printStackTrace();}}}}//拋出處理private static void method1() throws IOException {FileReader fr = new FileReader("fr.txt");FileWriter fw = new FileWriter("fw.txt");char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}fw.close();fr.close();} }05_標準輸入流
? ?
4.1、標準輸入輸出流
System類中有兩個靜態的成員變量:
- public static final InputStream in? :標準輸入流。通常該流對應于鍵盤輸入或由主機環境或用戶指定的另一個輸入源。
- public static final PrintStream out:標準輸出流。通常該流對應于顯示輸出或由主機環境或用戶指定的另一個輸出目標。
自己實現鍵盤錄入數據:
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
自己實現鍵盤錄入數據太麻煩了,所以Java就提供了一個類供我們使用:
- Scanner sc = new Scanner(System.in); // xxx.nextLine();? ?xxx.nextInt(); ...
06_標準輸出流
4.1、標準輸入輸出流
System類中有兩個靜態的成員變量:
- public static final InputStream in? :標準輸入流。通常該流對應于鍵盤輸入或由主機環境或用戶指定的另一個輸入源。
- public static final PrintStream out:標準輸出流。通常該流對應于顯示輸出或由主機環境或用戶指定的另一個輸出目標。
輸出語句的本質:是一個標準的輸出流。
- PrintStream ps = System.out;
- PrintStream類有的方法,System.out都可以使用。
?...
07_字節打印流
4.2、打印流
打印流分類
- 字節打印流:PrintStream
- 字符打印流:PrintWriter
打印流的特點:
- 只負責輸出數據,不負責讀取數據;
- 永遠不會拋出IOException;
- 有自己的特有方法。
字節打印流
- PrintStream(String fileName):使用指定的文件名創建新的打印流。
- 使用繼承父類的方法寫數據,查看的時候會轉碼;使用自己的特有方法寫數據,查看的數據原樣輸出。
- 可以改變輸出語句的目的地。
public static void setOut(PrintStream out):重新分配“標準”輸出流
08_字符打印流
4.2、打印流
字符打印流PrintWriter的構造方法:
??
PrintWriter?(Writer out, boolean autoFlush):創建一個新的PrintWriter【實現自動刷新:autoFlush參數為true】
09_復制Java文件打印流改進版
案例:復制Java文件(打印流改進版)
10_對象序列化流
4.3、對象序列化流
對象序列化介紹
- 對象序列化:就是將對象保存到磁盤中,或者在網絡中傳輸對象。
- 這種機制就是使用一個字節序列表示一個對象,該字節序列包含:對象的類型、對象的數據和對象中存儲的屬性等信息。
- 字節序列寫到文件之后,相當于文件中持久保存了一個對象的信息;
- 反之,該字節序列還可以從文件中讀取回來,重構對象,對它進行反序列化。
要實現序列化和反序列化就要使用對象序列化流和對象反序列化流:
- 對象序列化流: ObjectOutputStream
- 對象反序列化流:ObjectInputStream
對象序列化流: ObjectOutputStream
- 將Java對象的原始數據類型和圖形寫入OutputStream。可以使用ObjectInputStream讀取(重構)對象??梢酝ㄟ^使用流的文件來實現對象的持久存儲。如果流是網絡套接字流,則可以在另一個主機上或另一個進程中重構對象。
構造方法:
- ObjectOutputStream?(OutputStream out):創建一個寫入指定的OutputStream的ObjectOutputStream
序列化對象的方法:
- void writeObject?(Object obj):將指定的對象寫入ObjectOutputStream
注意:?
- 一個對象要想被序列化,該對象所屬的類必須必須實現Serializable接口。
- Serializable是一個標記接口,實現該接口,不需要重寫任何方法。
- NotSerializableException:拋出一個實例需要一個Serializable接口。 序列化運行時或實例的類可能會拋出此異常。
- 類的序列化由實現java.io.Serializable接口的類啟用。不實現此接口的類將不會使任何狀態序列化或反序列化。
??
11_對象反序列化流
4.3、對象序列化流
對象反序列化流:ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream編寫的原始數據和對象。
構造方法:
- ObjectInputStream?(InputStream in):創建從指定的InputStream讀取的ObjectInputStream。
反序列化對象的方法:
- Object readObject?():從ObjectInputStream讀取一個對象。
12_serialVersionUID&transient
4.3、對象序列化流
用對象序列化流序列化了一個對象后,假如我們修改了對象所屬的類文件,讀取數據會不會出問題呢?
- 會出問題,拋出InvalidClassException異常。
? ? java.io.InvalidClassException:
? ? ? ? 當序列化運行時檢測到類中的以下問題之一時拋出:
? ? ? ? ? ? 類的串行版本與從流中讀取的類描述符的類型不匹配(√)
? ? ? ? ? ? 該類包含未知的數據類型
? ? ? ? ? ? 該類沒有可訪問的無參數構造函數
? ? com.itheima_03.Student; local class incompatible:
? ? stream classdesc serialVersionUID = -3743788623620386195,
? ? local class serialVersionUID = -247282590948908173
如果出問題了,如何解決呢?
- 重新序列化。給對象所屬的類加一個值serialVersionUID:【private static final long serialVersionUID = 42L;】
如果一個對象中的某個成員變量的值不想被序列化,又該如何實現呢?
- 給該成員變量加transient關鍵字修飾,該關鍵字標記的成員變量不參與序列化過程?!緋rivate transient int age;】
調用write()方法后,修改Student.java(添加toString()方法),調用read()方法:報錯 java.io.InvalidClassException。修改Student.java文件后,序列化ID發生改變!序列化ID前后不一致,導致出錯!!!
??
? ?
在Student.java文件中,增加“private static final long serialVersionUID = 42L;?”,調用write()方法,修改Student.java文件(注釋掉toString()方法),調用read()方法:無報錯!
如果一個對象中的某個成員變量的值不想被序列化,又該如何實現呢?
- 給該成員變量加transient關鍵字修飾,該關鍵字標記的成員變量不參與序列化過程。【private transient int age;】
不想讓外部知道Student對象的age變量 -->?private transient int age; // 不參與序列化過程, age變量默認為0
13_Properties作為Map集合的使用
4.4、Properties
Properties介紹
- 是一個Map體系的集合類。
- Properties可以保存到流中或從流中加載。
- 屬性列表中的每個鍵及其對應的值都是一個字符串。
練習:Properties作為Map集合的使用。
Hashtable與Map用法一致。
?Properties不能有泛型!
14_Properties作為Map集合的特有方法
4.4、Properties
Properties作為集合的特有方法:
15_Properties和IO流相結合的方法
4.4、Properties
Properties和IO流相結合的方法:
16_游戲次數
案例:游戲次數
? ?? ??
總結
以上是生活随笔為你收集整理的Java19-day10【标准输入输出流、字节字符打印流、对象序列化-反序列化流、serialVersionUIDtransient、Properties】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java18-day09【字节缓冲流、字
- 下一篇: LeetCode 01【两数之和】【Le