二十七、JavaIO(Properties&對象序列化)

1.IO流案例

1.1集合到文件數據排序改進版【應用】

1.1.1案例需求

  • 鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績)。要求按照成績總分從高到低寫入文本文件
  • 格式:姓名,語文成績,數學成績,英語成績 舉例:林青霞,98,99,100

1.1.2分析步驟

  1. 定義學生類
  2. 創建TreeSet集合,通過比較器排序進行排序
  3. 鍵盤錄入學生數據
  4. 創建學生對象,把鍵盤錄入的數據對應賦值給學生對象的成員變量
  5. 把學生對象添加到TreeSet集合
  6. 創建字符緩衝輸出流對象
  7. 遍歷集合,得到每一個學生對象
  8. 把學生對象的數據拼接成指定格式的字符串
  9. 調用字符緩衝輸出流對象的方法寫數據
  10. 釋放資源

1.1.3代碼實現

  • 學生類

    public class Student {
        // 姓名
        private String name;
        // 語文成績
        private int chinese;
        // 數學成績
        private int math;
        // 英語成績
        private int english;
    
        public Student() {
            super();
        }
    
        public Student(String name, int chinese, int math, int english) {
            super();
            this.name = name;
            this.chinese = chinese;
            this.math = math;
            this.english = english;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getChinese() {
            return chinese;
        }
    
        public void setChinese(int chinese) {
            this.chinese = chinese;
        }
    
        public int getMath() {
            return math;
        }
    
        public void setMath(int math) {
            this.math = math;
        }
    
        public int getEnglish() {
            return english;
        }
    
        public void setEnglish(int english) {
            this.english = english;
        }
    
        public int getSum() {
            return this.chinese + this.math + this.english;
        }
    }
    
  • 測試類

    public class TreeSetToFileDemo {
        public static void main(String[] args) throws IOException {
            //創建TreeSet集合,通過比較器排序進行排序
            TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
                @Override
                public 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;
                }
            });
    
            //鍵盤錄入學生數據
            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();
    
                //創建學生對象,把鍵盤錄入的數據對應賦值給學生對象的成員變量
                Student s = new Student();
                s.setName(name);
                s.setChinese(chinese);
                s.setMath(math);
                s.setEnglish(english);
    
                //把學生對象添加到TreeSet集合
                ts.add(s);
            }
    
            //創建字符緩衝輸出流對象
            BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\ts.txt"));
    
            //遍歷集合,得到每一個學生對象
            for (Student s : ts) {
                //把學生對象的數據拼接成指定格式的字符串
                //格式:姓名,語文成績,數學成績,英語成績
                StringBuilder sb = new StringBuilder();
                sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());
    
    //            調用字符緩衝輸出流對象的方法寫數據
                bw.write(sb.toString());
                bw.newLine();
                bw.flush();
            }
    
            //釋放資源
            bw.close();
        }
    }
    

1.2複製單級文件夾【應用】

1.2.1案例需求

  • 把“E:\itcast”這個文件夾複製到模塊目錄下

1.2.2分析步驟

  1. 創建數據源目錄File對象,路徑是E:\itcast

  2. 獲取數據源目錄File對象的名稱

  3. 創建目的地目錄File對象,路徑由(模塊名+第2步獲取的名稱)組成

  4. 判斷第3步創建的File是否存在,如果不存在,就創建

  5. 獲取數據源目錄下所有文件的File數組

  6. 遍歷File數組,得到每一個File對象,該File對象,其實就是數據源文件

  7. 獲取數據源文件File對象的名稱

  8. 創建目的地文件File對象,路徑由(目的地目錄+第7步獲取的名稱)組成

  9. 複製文件

    ​ 由於不清楚數據源目錄下的文件都是什麼類型的,所以採用字節流複製文件

    ​ 採用參數爲File的構造方法

1.2.3代碼實現

public class CopyFolderDemo {
    public static void main(String[] args) throws IOException {
        //創建數據源目錄File對象,路徑是E:\\itcast
        File srcFolder = new File("E:\\itcast");

        //獲取數據源目錄File對象的名稱(itcast)
        String srcFolderName = srcFolder.getName();

        //創建目的地目錄File對象,路徑名是模塊名+itcast組成(myCharStream\\itcast)
        File destFolder = new File("myCharStream",srcFolderName);

        //判斷目的地目錄對應的File是否存在,如果不存在,就創建
        if(!destFolder.exists()) {
            destFolder.mkdir();
        }

        //獲取數據源目錄下所有文件的File數組
        File[] listFiles = srcFolder.listFiles();

        //遍歷File數組,得到每一個File對象,該File對象,其實就是數據源文件
        for(File srcFile : listFiles) {
            //數據源文件:E:\\itcast\\mn.jpg
            //獲取數據源文件File對象的名稱(mn.jpg)
            String srcFileName = srcFile.getName();
            //創建目的地文件File對象,路徑名是目的地目錄+mn.jpg組成(myCharStream\\itcast\\mn.jpg)
            File destFile = new File(destFolder,srcFileName);
            //複製文件
            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();
    }
}

1.3複製多級文件夾【應用】

1.3.1案例需求

  • 把“E:\itcast”這個文件夾複製到 F盤目錄下

1.3.2分析步驟

  1. 創建數據源File對象,路徑是E:\itcast

  2. 創建目的地File對象,路徑是F:\

  3. 寫方法實現文件夾的複製,參數爲數據源File對象和目的地File對象

  4. 判斷數據源File是否是文件

    ​ 是文件:直接複製,用字節流

    ​ 不是文件:

     	 在目的地下創建該目錄
    
     	遍歷獲取該目錄下的所有文件的File數組,得到每一個File對象
    
     	回到3繼續(遞歸)
    

1.3.3代碼實現

public class CopyFoldersDemo {
    public static void main(String[] args) throws IOException {
        //創建數據源File對象,路徑是E:\\itcast
        File srcFile = new File("E:\\itcast");
        //創建目的地File對象,路徑是F:\\
        File destFile = new File("F:\\");

        //寫方法實現文件夾的複製,參數爲數據源File對象和目的地File對象
        copyFolder(srcFile,destFile);
    }

    //複製文件夾
    private static void copyFolder(File srcFile, File destFile) throws IOException {
        //判斷數據源File是否是目錄
        if(srcFile.isDirectory()) {
            //在目的地下創建和數據源File名稱一樣的目錄
            String srcFileName = srcFile.getName();
            File newFolder = new File(destFile,srcFileName); //F:\\itcast
            if(!newFolder.exists()) {
                newFolder.mkdir();
            }

            //獲取數據源File下所有文件或者目錄的File數組
            File[] fileArray = srcFile.listFiles();

            //遍歷該File數組,得到每一個File對象
            for(File file : fileArray) {
                //把該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();
    }
}

1.4複製文件的異常處理【應用】

1.4.1基本做法

public class CopyFileDemo {
    public static void main(String[] args) {

    }

    //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();
    }
}

1.4.2JDK7版本改進

public class CopyFileDemo {
    public static void main(String[] args) {

    }

    //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();
        }
    }
}

1.4.3JDK9版本改進

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();
        }
    }
}

2.IO特殊操作流

2.1標準輸入流【應用】

  • System類中有兩個靜態的成員變量

    • public static final InputStream in:標準輸入流。通常該流對應於鍵盤輸入或由主機環境或用戶指定的另一個輸入源
    • public static final PrintStream out:標準輸出流。通常該流對應於顯示輸出或由主機環境或用戶指定的另一個輸出目標
  • 自己實現鍵盤錄入數據

    public class SystemInDemo {
        public static void main(String[] args) throws IOException {
            //public static final InputStream in:標準輸入流
    //        InputStream is = System.in;
    
    //        int by;
    //        while ((by=is.read())!=-1) {
    //            System.out.print((char)by);
    //        }
    
            //如何把字節流轉換爲字符流?用轉換流
    //        InputStreamReader isr = new InputStreamReader(is);
    //        //使用字符流能不能夠實現一次讀取一行數據呢?可以
    //        //但是,一次讀取一行數據的方法是字符緩衝輸入流的特有方法
    //        BufferedReader br = new BufferedReader(isr);
    
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
            System.out.println("請輸入一個字符串:");
            String line = br.readLine();
            System.out.println("你輸入的字符串是:" + line);
    
            System.out.println("請輸入一個整數:");
            int i = Integer.parseInt(br.readLine());
            System.out.println("你輸入的整數是:" + i);
    
            //自己實現鍵盤錄入數據太麻煩了,所以Java就提供了一個類供我們使用
            Scanner sc = new Scanner(System.in);
        }
    }
    

2.2標準輸出流【應用】

  • System類中有兩個靜態的成員變量

    • public static final InputStream in:標準輸入流。通常該流對應於鍵盤輸入或由主機環境或用戶指定的另一個輸入源
    • public static final PrintStream out:標準輸出流。通常該流對應於顯示輸出或由主機環境或用戶指定的另一個輸出目標
  • 輸出語句的本質:是一個標準的輸出流

    • PrintStream ps = System.out;
    • PrintStream類有的方法,System.out都可以使用
  • 示例代碼

    public class SystemOutDemo {
        public static void main(String[] args) {
            //public static final PrintStream out:標準輸出流
            PrintStream ps = System.out;
    
            //能夠方便地打印各種數據值
    //        ps.print("hello");
    //        ps.print(100);
    
    //        ps.println("hello");
    //        ps.println(100);
    
            //System.out的本質是一個字節輸出流
            System.out.println("hello");
            System.out.println(100);
    
            System.out.println();
    //        System.out.print();
        }
    }
    

2.3字節打印流【應用】

  • 打印流分類

    • 字節打印流:PrintStream
    • 字符打印流:PrintWriter
  • 打印流的特點

    • 只負責輸出數據,不負責讀取數據
    • 永遠不會拋出IOException
    • 有自己的特有方法
  • 字節打印流

    • PrintStream(String fileName):使用指定的文件名創建新的打印流

    • 使用繼承父類的方法寫數據,查看的時候會轉碼;使用自己的特有方法寫數據,查看的數據原樣輸出

    • 可以改變輸出語句的目的地

      ​ public static void setOut(PrintStream out):重新分配“標準”輸出流

  • 示例代碼

    public class PrintStreamDemo {
        public static void main(String[] args) throws IOException {
            //PrintStream(String fileName):使用指定的文件名創建新的打印流
            PrintStream ps = new PrintStream("myOtherStream\\ps.txt");
    
            //寫數據
            //字節輸出流有的方法
    //        ps.write(97);
    
            //使用特有方法寫數據
    //        ps.print(97);
    //        ps.println();
    //        ps.print(98);
            ps.println(97);
            ps.println(98);
            
            //釋放資源
            ps.close();
        }
    }
    

2.4字符打印流【應用】

  • 字符打印流構造房方法

    方法名 說明
    PrintWriter(String fileName) 使用指定的文件名創建一個新的PrintWriter,而不需要自動執行刷新
    PrintWriter(Writer out, boolean autoFlush) 創建一個新的PrintWriter out:字符輸出流 autoFlush: 一個布爾值,如果爲真,則println , printf ,或format方法將刷新輸出緩衝區
  • 示例代碼

    public class PrintWriterDemo {
        public static void main(String[] args) throws IOException {
            //PrintWriter(String fileName) :使用指定的文件名創建一個新的PrintWriter,而不需要自動執行行刷新
    //        PrintWriter pw = new PrintWriter("myOtherStream\\pw.txt");
    
    //        pw.write("hello");
    //        pw.write("\r\n");
    //        pw.flush();
    //        pw.write("world");
    //        pw.write("\r\n");
    //        pw.flush();
    
    //        pw.println("hello");
            /*
                pw.write("hello");
                pw.write("\r\n");
             */
    //        pw.flush();
    //        pw.println("world");
    //        pw.flush();
    
            //PrintWriter(Writer out, boolean autoFlush):創建一個新的PrintWriter
            PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),true);
    //        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),false);
    
            pw.println("hello");
            /*
                pw.write("hello");
                pw.write("\r\n");
                pw.flush();
             */
            pw.println("world");
    
            pw.close();
        }
    }
    

2.5複製Java文件打印流改進版【應用】

  • 案例需求

    • 把模塊目錄下的PrintStreamDemo.java 複製到模塊目錄下的 Copy.java
  • 分析步驟

    • 根據數據源創建字符輸入流對象
    • 根據目的地創建字符輸出流對象
    • 讀寫數據,複製文件
    • 釋放資源
  • 代碼實現

    public class CopyJavaDemo {
        public static void main(String[] args) throws IOException {
            /*
            //根據數據源創建字符輸入流對象
            BufferedReader br = new BufferedReader(new FileReader("myOtherStream\\PrintStreamDemo.java"));
            //根據目的地創建字符輸出流對象
            BufferedWriter bw = new BufferedWriter(new FileWriter("myOtherStream\\Copy.java"));
    
            //讀寫數據,複製文件
            String line;
            while ((line=br.readLine())!=null) {
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
    
            //釋放資源
            bw.close();
            br.close();
            */
    
            //根據數據源創建字符輸入流對象
            BufferedReader br = new BufferedReader(new FileReader("myOtherStream\\PrintStreamDemo.java"));
            //根據目的地創建字符輸出流對象
            PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\Copy.java"),true);
    
            //讀寫數據,複製文件
            String line;
            while ((line=br.readLine())!=null) {
                pw.println(line);
            }
    
            //釋放資源
            pw.close();
            br.close();
        }
    }
    

2.6對象序列化流【應用】

  • 對象序列化介紹

    • 對象序列化:就是將對象保存到磁盤中,或者在網絡中傳輸對象
    • 這種機制就是使用一個字節序列表示一個對象,該字節序列包含:對象的類型、對象的數據和對象中存儲的屬性等信息
    • 字節序列寫到文件之後,相當於文件中持久保存了一個對象的信息
    • 反之,該字節序列還可以從文件中讀取回來,重構對象,對它進行反序列化
  • 對象序列化流: ObjectOutputStream

    • 將Java對象的原始數據類型和圖形寫入OutputStream。 可以使用ObjectInputStream讀取(重構)對象。 可以通過使用流的文件來實現對象的持久存儲。 如果流是網絡套接字流,則可以在另一個主機上或另一個進程中重構對象
  • 構造方法

    方法名 說明
    ObjectOutputStream(OutputStream out) 創建一個寫入指定的OutputStream的ObjectOutputStream
  • 序列化對象的方法

    方法名 說明
    void writeObject(Object obj) 將指定的對象寫入ObjectOutputStream
  • 示例代碼

    • 學生類

      public class Student implements Serializable {
          private String name;
          private int age;
      
          public Student() {
          }
      
          public Student(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
    • 測試類

      public class ObjectOutputStreamDemo {
          public static void main(String[] args) throws IOException {
              //ObjectOutputStream(OutputStream out):創建一個寫入指定的OutputStream的ObjectOutputStream
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
      
              //創建對象
              Student s = new Student("林青霞",30);
      
              //void writeObject(Object obj):將指定的對象寫入ObjectOutputStream
              oos.writeObject(s);
      
              //釋放資源
              oos.close();
          }
      }
      
  • 注意事項

    • 一個對象要想被序列化,該對象所屬的類必須必須實現Serializable 接口
    • Serializable是一個標記接口,實現該接口,不需要重寫任何方法

2.7對象反序列化流【應用】

  • 對象反序列化流: ObjectInputStream

    • ObjectInputStream反序列化先前使用ObjectOutputStream編寫的原始數據和對象
  • 構造方法

    方法名 說明
    ObjectInputStream(InputStream in) 創建從指定的InputStream讀取的ObjectInputStream
  • 反序列化對象的方法

    方法名 說明
    Object readObject() 從ObjectInputStream讀取一個對象
  • 示例代碼

    public class ObjectInputStreamDemo {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            //ObjectInputStream(InputStream in):創建從指定的InputStream讀取的ObjectInputStream
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
    
            //Object readObject():從ObjectInputStream讀取一個對象
            Object obj = ois.readObject();
    
            Student s = (Student) obj;
            System.out.println(s.getName() + "," + s.getAge());
    
            ois.close();
        }
    }
    

2.8serialVersionUID&transient【應用】

  • serialVersionUID

    • 用對象序列化流序列化了一個對象後,假如我們修改了對象所屬的類文件,讀取數據會不會出問題呢?
      • 會出問題,會拋出InvalidClassException異常
    • 如果出問題了,如何解決呢?
      • 重新序列化
      • 給對象所屬的類加一個serialVersionUID
        • private static final long serialVersionUID = 42L;
  • transient

    • 如果一個對象中的某個成員變量的值不想被序列化,又該如何實現呢?
      • 給該成員變量加transient關鍵字修飾,該關鍵字標記的成員變量不參與序列化過程
  • 示例代碼

    • 學生類

      public class Student implements Serializable {
          private static final long serialVersionUID = 42L;
          private String name;
      //    private int age;
          private transient int age;
      
          public Student() {
          }
      
          public Student(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
      //    @Override
      //    public String toString() {
      //        return "Student{" +
      //                "name='" + name + '\'' +
      //                ", age=" + age +
      //                '}';
      //    }
      }
      
    • 測試類

      public class ObjectStreamDemo {
          public static void main(String[] args) throws IOException, ClassNotFoundException {
      //        write();
              read();
          }
      
          //反序列化
          private static void read() throws IOException, ClassNotFoundException {
              ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
              Object obj = ois.readObject();
              Student s = (Student) obj;
              System.out.println(s.getName() + "," + s.getAge());
              ois.close();
          }
      
          //序列化
          private static void write() throws IOException {
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
              Student s = new Student("林青霞", 30);
              oos.writeObject(s);
              oos.close();
          }
      }
      

3.Properties集合

3.1Properties作爲Map集合的使用【應用】

  • Properties介紹

    • 是一個Map體系的集合類
    • Properties可以保存到流中或從流中加載
    • 屬性列表中的每個鍵及其對應的值都是一個字符串
  • Properties基本使用

    public class PropertiesDemo01 {
        public static void main(String[] args) {
            //創建集合對象
    //        Properties<String,String> prop = new Properties<String,String>(); //錯誤
            Properties prop = new Properties();
    
            //存儲元素
            prop.put("itheima001", "林青霞");
            prop.put("itheima002", "張曼玉");
            prop.put("itheima003", "王祖賢");
    
            //遍歷集合
            Set<Object> keySet = prop.keySet();
            for (Object key : keySet) {
                Object value = prop.get(key);
                System.out.println(key + "," + value);
            }
        }
    }
    

3.2Properties作爲Map集合的特有方法【應用】

  • 特有方法

    方法名 說明
    Object setProperty(String key, String value) 設置集合的鍵和值,都是String類型,底層調用 Hashtable方法 put
    String getProperty(String key) 使用此屬性列表中指定的鍵搜索屬性
    Set stringPropertyNames() 從該屬性列表中返回一個不可修改的鍵集,其中鍵及其對應的值是字符串
  • 示例代碼

    public class PropertiesDemo02 {
        public static void main(String[] args) {
            //創建集合對象
            Properties prop = new Properties();
    
            //Object setProperty(String key, String value):設置集合的鍵和值,都是String類型,底層調用Hashtable方法put
            prop.setProperty("itheima001", "林青霞");
            /*
                Object setProperty(String key, String value) {
                    return put(key, value);
                }
    
                Object put(Object key, Object value) {
                    return map.put(key, value);
                }
             */
            prop.setProperty("itheima002", "張曼玉");
            prop.setProperty("itheima003", "王祖賢");
    
            //String getProperty(String key):使用此屬性列表中指定的鍵搜索屬性
    //        System.out.println(prop.getProperty("itheima001"));
    //        System.out.println(prop.getProperty("itheima0011"));
    
    //        System.out.println(prop);
    
            //Set<String> stringPropertyNames():從該屬性列表中返回一個不可修改的鍵集,其中鍵及其對應的值是字符串
            Set<String> names = prop.stringPropertyNames();
            for (String key : names) {
    //            System.out.println(key);
                String value = prop.getProperty(key);
                System.out.println(key + "," + value);
            }
        }
    }
    

3.3Properties和IO流相結合的方法【應用】

  • 和IO流結合的方法

    方法名 說明
    void load(InputStream inStream) 從輸入字節流讀取屬性列表(鍵和元素對)
    void load(Reader reader) 從輸入字符流讀取屬性列表(鍵和元素對)
    void store(OutputStream out, String comments) 將此屬性列表(鍵和元素對)寫入此 Properties表中,以適合於使用 load(InputStream)方法的格式寫入輸出字節流
    void store(Writer writer, String comments) 將此屬性列表(鍵和元素對)寫入此 Properties表中,以適合使用 load(Reader)方法的格式寫入輸出字符流
  • 示例代碼

    public class PropertiesDemo03 {
        public static void main(String[] args) throws IOException {
            //把集合中的數據保存到文件
    //        myStore();
    
            //把文件中的數據加載到集合
            myLoad();
    
        }
    
        private static void myLoad() throws IOException {
            Properties prop = new Properties();
    
            //void load(Reader reader):
            FileReader fr = new FileReader("myOtherStream\\fw.txt");
            prop.load(fr);
            fr.close();
    
            System.out.println(prop);
        }
    
        private static void myStore() throws IOException {
            Properties prop = new Properties();
    
            prop.setProperty("itheima001","林青霞");
            prop.setProperty("itheima002","張曼玉");
            prop.setProperty("itheima003","王祖賢");
    
            //void store(Writer writer, String comments):
            FileWriter fw = new FileWriter("myOtherStream\\fw.txt");
            prop.store(fw,null);
            fw.close();
        }
    }
    

3.4遊戲次數案例【應用】

  • 案例需求

    • 實現猜數字小遊戲只能試玩3次,如果還想玩,提示:遊戲試玩已結束,想玩請充值(www.itcast.cn)
  • 分析步驟

    1. 寫一個遊戲類,裏面有一個猜數字的小遊戲

    2. 寫一個測試類,測試類中有main()方法,main()方法中寫如下代碼:

      ​ 從文件中讀取數據到Properties集合,用load()方法實現

         文件已經存在:game.txt
      
         裏面有一個數據值:count=0
      

      ​ 通過Properties集合獲取到玩遊戲的次數

      ​ 判斷次數是否到到3次了

         如果到了,給出提示:遊戲試玩已結束,想玩請充值(www.itcast.cn)
      
         如果不到3次:
      
         	次數+1,重新寫回文件,用Properties的store()方法實現玩遊戲
      
  • 代碼實現

    public class PropertiesTest {
        public static void main(String[] args) throws IOException {
            //從文件中讀取數據到Properties集合,用load()方法實現
            Properties prop = new Properties();
    
            FileReader fr = new FileReader("myOtherStream\\game.txt");
            prop.load(fr);
            fr.close();
    
            //通過Properties集合獲取到玩遊戲的次數
            String count = prop.getProperty("count");
            int number = Integer.parseInt(count);
    
            //判斷次數是否到到3次了
            if(number >= 3) {
                //如果到了,給出提示:遊戲試玩已結束,想玩請充值(www.itcast.cn)
                System.out.println("遊戲試玩已結束,想玩請充值(www.itcast.cn)");
            } else {
                //玩遊戲
                GuessNumber.start();
    
                //次數+1,重新寫回文件,用Properties的store()方法實現
                number++;
                prop.setProperty("count",String.valueOf(number));
                FileWriter fw = new FileWriter("myOtherStream\\game.txt");
                prop.store(fw,null);
                fw.close();
            }
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章