day05
對象流:
ObjectOutputStream 對象輸出流
ObjectInputStream 對象輸入流
對象流是一組高級流,作用是通過這組流可以方便的讀寫java中的任何對象.
1. 對象輸出流:ObjectOutputStream 用于寫出對象,由于底層讀寫都是字節(jié)讀寫,所以無論什么樣的數(shù)據(jù)都要轉(zhuǎn)換為字節(jié)才能寫出.對象輸出流可以自行將給定的對象轉(zhuǎn)換為一組字節(jié)然后寫出.省去了我們將對象按照結(jié)構(gòu)轉(zhuǎn)化為字節(jié)的麻煩.
ObjectOutputStream提供了寫對象的方法:
void writeObject(Object obj)
該方法會將給定的對象轉(zhuǎn)換為一組字節(jié)然后通過其處理的流寫出
這里涉及到兩個操作:
1) 對象序列化:將一個對象按照結(jié)構(gòu)轉(zhuǎn)換為一組字節(jié)的過程
2) 對象持久化:將該對象寫入文件(硬盤中)的過程.
2. 對象輸入流:ObjectInputStream 用于進(jìn)行對象反序列化
public class am03_ObjectOutputStream_writeObject {
public static void main(String[] args) throws IOException {
/*
* 將一個Person實例寫入文件保存
*/
am02_Person p = new am02_Person();
p.setName("蒼老師");
p.setAge(18);
p.setGender("女");
String[] otherInfo = {"是一名演員","愛好是寫毛筆字","促進(jìn)中日文化交流","廣大男性同胞的啟蒙老師"};
p.setOtherInfo(otherInfo);
System.out.println(p);
/*
* 文件輸出流作用:將給定的字節(jié)寫入到指定文件
*/
FileOutputStream fos
= new FileOutputStream("person.obj");
/*
* 對象輸出流作用:將給定的java對象轉(zhuǎn)換為一組
* 字節(jié)后寫出
*/
ObjectOutputStream oos
= new ObjectOutputStream(fos);
/*
* ObjectOutputStream提供了寫對象的
* 方法:
* void writeObject(Object obj)
* 該方法會將給定的對象轉(zhuǎn)換為一組字節(jié)然后
* 通過其處理的流寫出
*
*
* 這里的操作是先通過OOS將p對象轉(zhuǎn)換為
* 了一組字節(jié),然后再將該組字節(jié)通過FOS
* 寫入到了文件person.obj中
* 這里涉及到兩個操作:
* 1:對象序列化.將一個對象按照結(jié)構(gòu)轉(zhuǎn)換
* 為一組字節(jié)的過程
* 2:對象持久化.將該對象寫入文件(硬盤中)
* 的過程.
*
*/
oos.writeObject(p);
System.out.println("寫出完畢!");
oos.close();
}
}
public class am04_ObjectInputStream_readObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis
= new FileInputStream("person.obj");
ObjectInputStream ois
= new ObjectInputStream(fis);
/*
* ObjectInputStream提供方法:
* Object readObject()
* 該方法可以讀取字節(jié)并還原為指定的對象
* 需要確保OIS讀取的字節(jié)是通過對象輸出流(OOS)
* 將一個對象寫出的字節(jié).否則會拋出異常.
*/
am02_Person p = (am02_Person)ois.readObject();
System.out.println(p);
ois.close();
}
}
轉(zhuǎn)換流:
OutputStreamWriter,InputStreamReader
java根據(jù)讀寫數(shù)據(jù)的單位劃分了:字節(jié)流,字符流
InputStream,OutputStream是所有字節(jié)輸入流與
字節(jié)輸出流的父類,常用實現(xiàn)類:FileInputStream,
BufferedInputStream等.
Reader,Writer是所有字符輸入流與字符輸出流的父類
字節(jié)流的讀寫單位是字節(jié),而字符流的讀寫單位是字符.
所以字符流有局限性,只適合讀寫字符數(shù)據(jù).
但實際字符流底層本質(zhì)還是讀寫字節(jié),只是字符與字節(jié)
的轉(zhuǎn)換工作不用我們來做了.
public class pm01_OutputStreamWriter_write {
public static void main(String[] args) throws IOException {
FileOutputStream fos
= new FileOutputStream("osw.txt");
/*
* 構(gòu)造方法若只傳入流,那么通過當(dāng)前轉(zhuǎn)換流
* 寫出的字符會按照系統(tǒng)默認(rèn)的字符集轉(zhuǎn)化為
* 對應(yīng)的字節(jié),不推薦.
* 可以使用重載的構(gòu)造方法,在第二個參數(shù)中
* 明確使用的字符集.
*/
OutputStreamWriter osw
= new OutputStreamWriter(fos,"GBK");
String str = "夜空中最亮的星,能否聽清.";
osw.write(str);
osw.write("那仰望的人,心底的孤獨和嘆息.");
System.out.println("寫出完畢!");
osw.close();
}
}
public class pm02_InputStreamReader_read {
public static void main(String[] args) throws IOException {
FileInputStream fis
= new FileInputStream("osw.txt");
InputStreamReader isr
= new InputStreamReader(fis,"GBK");
// char[] data = new char[100];
// int len = isr.read(data);
// String str = new String(data,0,len);
// System.out.println(str);
StringBuilder builder = new StringBuilder();
String str = "";
int d = -1;
while((d = isr.read())!=-1){
builder.append((char)d);
}
str = builder.toString();
System.out.println(str);
isr.close();
}
}
緩沖字符流:
PrintWriter
緩沖字符流由于內(nèi)部有緩沖區(qū),讀寫字符的效率高.
并且字符流的特點是可以按行讀寫字符串.
BufferedWriter,BufferedReader
PrintWriter也是緩沖字符輸出流,它內(nèi)部總是連接
BufferedWriter,除此之外PW還提供了自動行刷新
功能.所以更常用.
PrintWriter提供了直接對文件進(jìn)行寫操作
的構(gòu)造方法:
PrintWriter(File file)
PrintWriter(String fileName)
若希望按照指定的字符集向文件寫出字符串,
可以使用對應(yīng)重載的構(gòu)造方法:
PrintWriter(File file,String csn)
PrintWriter(String fileName,String csn)
第二個參數(shù)可以指定字符集的名字(charSetName)
public class pm03_PrintWriter_println {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
/*
* PrintWriter提供了直接對文件進(jìn)行寫操作
* 的構(gòu)造方法:
* PrintWriter(File file)
* PrintWriter(String fileName)
* 若希望按照指定的字符集向文件寫出字符串,
* 可以使用對應(yīng)重載的構(gòu)造方法:
* PrintWriter(File file,String csn)
* PrintWriter(String fileName,String csn)
* 第二個參數(shù)可以指定字符集的名字(charSetName)
*/
PrintWriter pw
= new PrintWriter("pw.txt","GBK");
pw.println("董小姐,你從沒忘記你的微笑.");
pw.println("就算你和我一樣,渴望著衰老.");
System.out.println("寫出完畢!");
pw.close();
}
}
PrintWriter提供了常規(guī)的構(gòu)造方法,允許傳入
一個字節(jié)流或者字符流完成流連接的創(chuàng)建形式
public class pm04_PrintWriter_println2 {
public static void main(String[] args) throws IOException {
FileOutputStream fos
= new FileOutputStream("pw2.txt");
/*
* 若希望指定字符集,需要自行連接轉(zhuǎn)換流
* 因為轉(zhuǎn)換流可以將字符按照指定的字符集
* 轉(zhuǎn)換為字節(jié)
*/
OutputStreamWriter osw
= new OutputStreamWriter(fos,"GBK");
PrintWriter pw
= new PrintWriter(osw);
/*
* PW的構(gòu)造方法允許直接傳入字節(jié)流,但實際
* 內(nèi)部還是會根據(jù)流連接最終變?yōu)镻W的.只是
* 這樣做不能指定字符集
*/
// PrintWriter pw
// = new PrintWriter(fos);
pw.println("我在二環(huán)路的里邊,想著你.");
pw.println("你在遠(yuǎn)方的山上,春風(fēng)十里.");
pw.close();
}
}
緩沖字符輸入流:
BufferedReader
/**
* java.io.BufferedReader
* 緩沖字符輸入流.特點:可以按行讀取字符串
* 由于有緩沖,讀取字符時的效率好.
*/
public class pm06_BufferedReader_readLine {
public static void main(String[] args) throws IOException {
/*
./JSD1708_SE\src\day05
*/
FileInputStream fis = new FileInputStream("./JSD1708_SE"+ File.separator+"src"+File.separator+"day05"+File.separator+"pm06_BufferedReader_readLine.java");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
練習(xí):
/**
* 簡易記事本
* 使用PW將用戶輸入的每行字符串寫入用戶指定的文件中
* 構(gòu)造方法使用流連接形式,不使用直接對文件操作的.
*/
public class pm05_Note {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入一個文件名:");
String fileName = scanner.nextLine();
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter osw = new OutputStreamWriter(fos);
/*
當(dāng)PrintWriter的構(gòu)造方法第一個參數(shù)為流(字節(jié)流,字符流均可)時,
那么支持一個重載的構(gòu)造方法可以傳入一個boolean值,該值若為true
,則當(dāng)前PrintWriter具有自動刷新功能即:每當(dāng)調(diào)用Println方法寫出
一行字符串后會
自動調(diào)用flush方法將其真實寫出.
需要注意,調(diào)用print方法是不會flush的
*/
PrintWriter pw = new PrintWriter(osw,true);
System.out.println("請開始你的表演");
String line = null;
while (true) {
line = scanner.nextLine();
if (line.equals("exit")) {
break;
}
pw.println(line);
}
System.out.println("再見!");
pw.close();
}
}