day38-IO流05
JavaIO流05
4.常用的類04
4.4節點流和處理流03
4.4.8列印流-PrintStream和PrintWriter
列印流只有輸出流,沒有輸入流
1.簡單介紹及應用
- PrintStream是位元組列印流
例子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
}
}
運行結果:
如上所示:在修改了列印流 輸出的位置/設備之後,再調用System.out.println
方法,列印/輸出的地方就變為指定的文件路徑,點擊System.setOut
方法,可以看到底層是調用了setOut0
方法,該方法是本地方法(native)。它會去修改out,即修改輸出數據的位置:
- PrintWriter是字元列印流
例子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()+關閉流,才會將數據寫入到文件中
}
}
4.5Properties類
- 看一個需求:
如下一個配置文件 mysql.properties:
ip=192.168.0.13
user=root
pwd=12345
問編程讀取ip、user、pwd的值是多少要怎麼做?
分析:
- 傳統的方法
- 使用Properties類可以方便實現
例子:傳統方法
在scr文件夾下創建一個mysql.properties文件,內容為
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();
}
}
如上所示,如果mysql.properties的參數很多,並且要求讀取修改其中一項或者n項參數,那麼使用傳統的讀取方法,就需要我們對讀取的參數進行條件判斷,一旦要讀取的參數過多,程式碼就會變得非常繁瑣。這時候就需要使用到Properties類。
4.5.1基本介紹
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);
}
}
應用案例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("保存配置文件成功~");
}
}
查詢發現 \u6C64\u59C6 對應的中文就是 湯姆
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();
}
}
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();
}
}
要求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
編程題:
-
要編寫一個dog.properties
name=tom age=5 color=red
-
編寫Dog類(name,age,color)創建一個dog對象,讀取dog.properties 用相應的內容完成初始化,並輸出
-
將創建的Dog對象,序列化到 文件 dog.dat文件
-
再反序列化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 + '\'' +
'}';
}
}