day38-IO流05

JavaIO流05

4.常用的類04

4.4節點流和處理流03

4.4.8列印流-PrintStream和PrintWriter

列印流只有輸出流,沒有輸入流

1.簡單介紹及應用
  • PrintStream是位元組列印流

image-20220913170815891

例子1:演示PrintStream(位元組列印流/輸出流)

package li.io.printstream;

import java.io.IOException;
import java.io.PrintStream;

/**
 * 演示PrintStream(位元組列印流/輸出流)
 */
public class PrintStream_ {
    public static void main(String[] args) throws IOException {
        PrintStream out = System.out;
        //在默認情況下,PrintStream 輸出數據的位置是 標準輸出,即顯示器
        out.print("jack,hello");
        /**
         *   public void print(String s) {
         *         if (s == null) {
         *             s = "null";
         *         }
         *         write(s);
         *     }
         */
        //因為print底層使用的是write,所以我們可以直接調用write進行列印/輸出
        out.write("Hello北京".getBytes());
        out.close();

        //我們可以去修改列印流輸出的位置/設備
        // 1.修改為列印到d:\f1.txt
        // 2."落霞與孤鶩齊飛,秋水共長天一色" 這句話就會列印到d:\f1.txt里
        // 3.System.setOut底層:
        /**
         *     public static void setOut(PrintStream out) {
         *         checkIO();
         *         setOut0(out);//native方法 ,修改了 out
         *     }
         */
        System.setOut(new PrintStream("d:\\f1.txt"));
        System.out.println("落霞與孤鶩齊飛,秋水共長天一色");//列印到d:\f1.txt

    }
}

運行結果:

image-20220913172623918
image-20220913172650672

如上所示:在修改了列印流 輸出的位置/設備之後,再調用System.out.println方法,列印/輸出的地方就變為指定的文件路徑,點擊System.setOut方法,可以看到底層是調用了setOut0方法,該方法是本地方法(native)。它會去修改out,即修改輸出數據的位置:

image-20220913173355950
image-20220913173010911


  • PrintWriter是字元列印流

image-20220913170726100

例子2:

package li.io.printstream;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 演示PrintWriter的使用方式
 */
public class PrintWriter_ {
    public static void main(String[] args) throws IOException {

        //PrintWriter printWriter = new PrintWriter(System.out);
        //向PrintWriter構造器中傳入一個FileWriter對象
        PrintWriter printWriter = new PrintWriter(new FileWriter("d:\\f2.txt"));
        printWriter.print("hi,北京你好~");
        printWriter.close();//flush()+關閉流,才會將數據寫入到文件中

    }
}

image-20220913175747776

4.5Properties類

  • 看一個需求:

如下一個配置文件 mysql.properties:

ip=192.168.0.13
user=root
pwd=12345

問編程讀取ip、user、pwd的值是多少要怎麼做?

分析:

  1. 傳統的方法
  2. 使用Properties類可以方便實現

例子:傳統方法

在scr文件夾下創建一個mysql.properties文件,內容為

image-20220913184108604

package li.io.properties_;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Properties01 {
    public static void main(String[] args) throws IOException {

        //讀取mysql.properties文件,並得到ip,user,pwd
        //創建
        BufferedReader br = new BufferedReader(new FileReader("src\\mysql.properties"));
        String line = "";
        //讀取
        while ((line = br.readLine()) != null) {//循環讀取
            String[] split = line.split("=");
            System.out.println(split[0] + "值是: " + split[1]);
        }
        //關閉
        br.close();
    }
}

image-20220913182215069

如上所示,如果mysql.properties的參數很多,並且要求讀取修改其中一項或者n項參數,那麼使用傳統的讀取方法,就需要我們對讀取的參數進行條件判斷,一旦要讀取的參數過多,程式碼就會變得非常繁瑣。這時候就需要使用到Properties類。

4.5.1基本介紹

image-20220913182758708

Properties是Hashtable的子類,是專門用於讀寫配置文件的集合類:

1)配置文件的格式:

鍵=值
鍵=值

2)注意:鍵值對之間不需要有空格,值不需要用引號括起來。默認的類型是String

3)Properties的常見方法:

  • load:載入配置文件的鍵值對到Properties對象
  • list:將數據顯示到指定設備/流對象
  • getProperty(Key):根據鍵獲取值
  • setProperty(Key,Value):設置鍵值對到Properties對象
  • store:將Properties中的鍵值對存儲到配置文件中,在idea中,保存資訊到配置文件,如果含有中文,會存儲為unicode碼

應用案例1:使用Properties類完成對mysql.properties 的讀取

package li.io.properties_;

import java.io.IOException;
import java.io.FileReader;
import java.util.Properties;

public class Properties02 {
    public static void main(String[] args) throws IOException {
        //使用Properties類來讀取 mysql.properties 文件

        // 1.創建Properties對象
        Properties properties = new Properties();

        // 2.載入指定的配置文件
        properties.load(new FileReader("src\\mysql.properties"));

        // 3.將 k-v 顯示到控制台
        properties.list(System.out);

        // 4.根據key獲取對應的值
        String user = properties.getProperty("user");
        String pwd = properties.getProperty("pwd");
        System.out.println("用戶名=" + user);
        System.out.println("密碼=" + pwd);
    }
}

image-20220913185319970

應用案例2:使用Properties類添加 key-value 到新文件 mysql2.properties 中,並修改某個 key-value

package li.io.properties_;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class Properties03 {
    public static void main(String[] args) throws IOException {
        //使用Properties類添加 key-value 到新文件 mysql2.properties 中

        //創建對象
        Properties properties = new Properties();
        //創建
        //如果該文件沒有key,就是創建
        //如果該文件有key,就是修改/替換
        /**
         * Properties類的父類就是 Hashtable ,底層就是 Hashtable的核心方法
         * public synchronized V put(K key, V value) {
         *         // Make sure the value is not null
         *         if (value == null) {
         *             throw new NullPointerException();
         *         }
         *
         *         // Makes sure the key is not already in the hashtable.
         *         Entry<?,?> tab[] = table;
         *         int hash = key.hashCode();
         *         int index = (hash & 0x7FFFFFFF) % tab.length;
         *         @SuppressWarnings("unchecked")
         *         Entry<K, V> entry = (Entry<K,V>)tab[index];
         *         for(; entry != null ; entry = entry.next) {
         *             if ((entry.hash == hash) && entry.key.equals(key)) {
         *                 V old = entry.value;//如果key存在,就替換
         *                 entry.value = value;
         *                 return old;
         *             }
         *         }
         *
         *         addEntry(hash, key, value, index);//如果是新的key,就添加新 key
         *         return null;
         *     }
         */
        properties.setProperty("charset", "utf-8");
        properties.setProperty("user", "湯姆");//注意:保存的是中文的Unicode碼值
        properties.setProperty("pwd", "abcd123");
        properties.setProperty("pwd", "1111");//替換
        //將k-v存儲到文件中即可
        properties.store(new FileOutputStream("src\\mysql2.properties"), null);//第二個參數是添加註釋
        System.out.println("保存配置文件成功~");

    }
}

image-20220913191459178

查詢發現 \u6C64\u59C6 對應的中文就是 湯姆

image-20220913190339285

5.IO習題

5.1Homework01

(1)判斷d盤下是否有文件夾mytemp,如果沒有就創建mytemp

(2)在d:\mytemp目錄下,創建文件hello.txt

(3)如果hello.txt已經存在,就提示該文件已經存在,就不要重複創建了

(4)並在hello.txt文件中寫入內容”hello,world”.

package li.io.homework;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class HomeWork01 {
    public static void main(String[] args) throws IOException {

        String filePath = "d:\\mytemp\\hello.txt";
        String dictionaryPath = "d:\\mytemp";

        //創建對象
        File file = new File(dictionaryPath);//目錄
        File file2 = new File(filePath);//文件
        FileOutputStream fileOutputStream = null;

        if (!file.exists()) {//如果目錄不存在
            if (file.mkdir()) {//創建目錄
                System.out.println("創建目錄mytemp成功~");
            }
        } else {
            System.out.println("目錄mytemp已存在");
        }

        if (file2.exists()) {
            System.out.println("hello.txt文件已存在");
            //如果文件存在,就寫入數據
            fileOutputStream = new FileOutputStream(filePath);
            fileOutputStream.write("hello,world".getBytes());
            System.out.println("已寫入數據~");
        } else {
            if (file2.createNewFile()) {
                System.out.println("創建hello.txt文件成功~");
                //如果文件存在,就寫入數據
                fileOutputStream = new FileOutputStream(filePath);
                fileOutputStream.write("hello,world".getBytes());
                System.out.println("已寫入數據~");
            }
        }

        //關閉流
        fileOutputStream.close();
    }
}

image-20220913201846941
image-20220913201940247

5.2Homework02

編程題:要求:使用BufferedReader讀取一個文本文件,為每行加上行號,再連同內容一併輸出到螢幕上。

package li.io.homework;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class HomeWork02 {
    public static void main(String[] args) throws IOException {
        
        String filePath = "d:\\story.txt";
        String line = "";
        int i = 0;//行號
        //創建對象
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        //讀取
        while ((line = br.readLine()) != null) {
            System.out.println((++i) + "\t" + line);
        }
        //關閉流
        br.close();
    }
}

image-20220913195105457

要求2:如果將文本的編碼改為GBK,怎麼將其輸出到控制台上而不使其亂碼?

使用轉換流,FileInputStream–>InputStreamReader(指定編碼)–>BufferedReader

package li.io.homework;

import java.io.*;

public class HomeWork02 {
    public static void main(String[] args) throws IOException {

        String filePath = "d:\\story.txt";
        String line = "";
        int i = 0;//行號
        //創建對象
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"GBK"));//使用轉換流,選擇編碼為「GBK」
        //讀取
        while ((line = br.readLine()) != null) {//循環讀取
            System.out.println((++i) + "\t" + line);
        }
        //關閉流
        br.close();
    }
}

5.3Homework03

編程題:

  1. 要編寫一個dog.properties

    name=tom
    age=5
    color=red
    
  2. 編寫Dog類(name,age,color)創建一個dog對象,讀取dog.properties 用相應的內容完成初始化,並輸出

  3. 將創建的Dog對象,序列化到 文件 dog.dat文件

  4. 再反序列化dog對象

package li.io.homework;

import java.io.*;
import java.util.Properties;

public class HomeWork03 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        //1.編寫dog.properties
        //創建Properties對象
        Properties properties = new Properties();
        //在properties對象中添加k-v
        properties.setProperty("name", "tom");
        properties.setProperty("age", "5");
        properties.setProperty("color", "red");
        //將properties對象的k-v存儲到文件中
        properties.store(new FileOutputStream("src\\dog.properties"), null);

        //2.讀取dog.properties完成Dog對象 的初始化
        int age = Integer.parseInt(properties.getProperty("age"));
        Dog dog = new Dog(properties.getProperty("name"), age, properties.getProperty("color"));
        System.out.println(dog);

        //3.將創建的Dog對象,序列化到 dog.dat文件
        String filePath = "d:\\dog.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
        oos.writeObject(dog);
        //關閉流
        oos.close();
        System.out.println("Dog序列化完成");

        //4.反序列化dog對象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        Dog dog1 = (Dog) ois.readObject();
        System.out.println(dog1);
        //關閉流
        ois.close();
        System.out.println("反序列化完成");
    }
}

//序列化的類要實現Serializable介面
class Dog implements Serializable {
    private String name;
    private int age;
    private String red;

    public Dog(String name, int age, String red) {
        this.name = name;
        this.age = age;
        this.red = red;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", red='" + red + '\'' +
                '}';
    }
}

image-20220913200658602
image-20220913212815401

Tags: