1.輸入字元流
1.1輸入輸出位元組流回顧
位元組流:
輸入位元組流
----------| InputStream 輸入位元組流的基類 抽象類
-------------|FileInputStream 讀取檔案資料的輸入位元組流。
-------------|BufferedInputStream 緩沖輸入位元組流
緩沖輸入位元組流出現的目的: 為了提高讀取檔案資料的效率。 該類其實内部就是維護了一個8kb位元組數組而已。
輸出位元組流:
---------| OutputStream 輸出位元組流的基類。 抽象類。
--------------| FileOutStream 向檔案輸出資料的輸出位元組流。
--------------| BufferedOutputStream 緩沖輸出位元組流。 該類出現的目的是為了提高寫資料的效率 。 其實該類内部也是維護了一個8kb的數組而已,當調用其write方法的時候資料預設是向它内部的數組中存儲 的,隻有調用flush方法或者是close方法或者是8kb的位元組數組存儲滿資料的時候才會真正的向硬碟輸出。
使用位元組流讀取和寫入中文
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) throws IOException {
// writeTest();
readrTest();
}
//使用位元組流讀取中文
public static void readrTest() throws IOException{
//找到目标檔案
File file = new File("F:\\a.txt");
//建立資料的輸入通道
FileInputStream fileInputStream = new FileInputStream(file);
//讀取内容
//int content = 0;
/*while((content = fileInputStream.read())!=-1){ //出現亂碼的原因: 一個中文在gbk碼表中預設是占兩個位元組,
// 目前你隻讀取了一個位元組而已,是以不是一個完整的中文。
System.out.print((char)content);
}*/
byte[] buf = new byte[2];
for(int i = 0 ; i < 3 ; i++){
fileInputStream.read(buf);
System.out.print(new String(buf));
}
//關閉資源
fileInputStream.close();
}
//使用位元組流寫中文。 位元組流之是以能夠寫中文是因為借助了字元串的getBytes方法對字
符串進行了編碼(字元---->數字)。
public static void writeTest() throws IOException{
//找到目标檔案
File file = new File("F:\\a.txt");
//建立資料的輸出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//準備資料,把資料寫出。
String data = "大家好";
byte[] buf = data.getBytes(); //把字元串轉換成位元組數組
System.out.println("輸出的内容:"+ Arrays.toString(buf));
fileOutputStream.write(buf);
///關閉資源
fileOutputStream.close();
}
}
1.2字元流
計算機并不區分二進制檔案與文本檔案。所有的檔案都是以二進制形式來存儲的,是以,從本質上說,所有的檔案都是二進制檔案。是以字元流是建立在位元組流之上的,它能夠提供字元層次的編碼和解碼。例如,在寫入一個字元時,Java虛拟機會将字元轉為檔案指定的編碼(預設是系統預設編碼),在讀取字元時,再将檔案指定的編碼轉化為字元。
1.3常見的碼表如下:
ASCII: 美國标準資訊交換碼。用一個位元組的7位可以表示。
ISO8859-1: 拉丁碼表。歐洲碼表,用一個位元組的8位表示。又稱Latin-1(拉丁編碼)或“西歐語言”。ASCII碼是包含的僅僅是英文字母,并且沒有完全占滿256個編碼位置,是以它以ASCII為基礎,在空置的0xA0-0xFF的範圍内,加入192個字母及符号,
藉以供使用變音符号的拉丁字母語言使用。進而支援德文,法文等。因而它依然是一個單位元組編碼,隻是比ASCII更全面。
GB2312: 英文占一個位元組,中文占兩個位元組.中國的中文編碼表。
GBK: 中國的中文編碼表更新,融合了更多的中文文字元号。
Unicode: 國際标準碼規範,融合了多種文字。所有文字都用兩個位元組來表示,Java語言使用的就是unicode。
UTF-8: 最多用三個位元組來表示一個字元。
(我們以後接觸最多的是iso8859-1、gbk、utf-8)
檢視上述碼表後,很顯然中文的‘中’在iso8859-1中是沒有對映的編碼的。或者一個字元在2中碼表中對應的編碼不同,例如有一些字在不同的編碼中是有交集的,例如bjg5 和gbk 中的漢字簡體和繁體可能是一樣的,就是有交集,但是在各自碼表中的數字不一樣。
例如
使用gbk 将中文儲存在計算機中,
中 國
對映 100 200 如果使用big5 打開
可能 ? ...
不同的編碼對映的是不一樣的。
很顯然,我們使用什麼樣的編碼寫資料,就需要使用什麼樣的編碼來對資料。
ISO8859-1:一個位元組
GBK: 兩個位元組包含了英文字元和擴充的中文 ISO8859-1+中文字元
UTF-8萬國碼,推行的。是1~3個位元組不等長。英文存的是1個位元組,中文存的是3個位元組,是為了節省空間。
位元組流:位元組流讀取的是檔案中的二進制資料,讀到的資料并不會幫你轉換成你看得懂的字元。
字元流: 字元流會把讀取到的二進制的資料進行對應 的編碼與解碼工作。 字元流= 位元組流 + 編碼(解碼)
輸入字元流:
----------| Reader 輸入字元流的基類 抽象類
-------------| FileReader 讀取檔案的輸入字元流。
FileReader的用法:
1. 找到目标檔案
2. 建立資料的輸入通道
3. 讀取資料
4. 關閉資源
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) throws IOException {
readTest2();
}
//使用緩沖字元數組讀取檔案。
public static void readTest2() throws IOException{
//找到目标檔案
File file = new File("F:\\1208project\\day21\\src\\day21\\Demo1.java");
// 建立資料的輸入通道
FileReader fileReader = new FileReader(file);
//建立緩沖字元數組讀取檔案資料
char[] buf = new char[1024];
int length = 0 ;
while((length = fileReader.read(buf))!=-1){
System.out.print(new String(buf,0,length));
}
}
public static void readTest1() throws IOException{
//找到目标檔案
File file = new File("F:\\1208project\\day21\\src\\day21\\Demo1.java");
//建立資料的輸入通道
FileReader fileReader = new FileReader(file);
int content = 0 ;
while((content = fileReader.read())!=-1){ //每次隻會讀取一個字元,效率低。
System.out.print((char)content);
}
//關閉資源
fileReader.close();
}
}
1.4 Reader
方法:
intread():
讀取一個字元。傳回的是讀到的那個字元。如果讀到流的末尾,傳回-1.
intread(char[]):
将讀到的字元存入指定的數組中,傳回的是讀到的字元個數,也就是往數組裡裝的元素的個數。如果讀到流的末尾,傳回-1.
close()
讀取字元其實用的是window系統的功能,就希望使用完畢後,進行資源的釋放
由于Reader也是抽象類,是以想要使用字元輸入流需要使用Reader的實作類。檢視API文檔。找到了FileReader。
1,用于讀取文本檔案的流對象。
2,用于關聯文本檔案。
構造函數:在讀取流對象初始化的時候,必須要指定一個被讀取的檔案。
如果該檔案不存在會發生FileNotFoundException.
public class IoTest1_Reader {
public static void main(String[] args) throws Exception {
String path = "c:/a.txt";
// readFileByInputStream(path);
readFileByReader(path);
}
/**
* 使用位元組流讀取檔案内容
* @param path
*/
public static void readFileByInputStream(String path) throws Exception {
InputStream in = new FileInputStream(path);
int len = 0;
while ((len = in.read()) != -1) {
System.out.print((char) len);
}
in.close();
}
/**
* 使用字元流讀取檔案内容
*/
public static void readFileByReader(String path) throws Exception {
Reader reader = new FileReader(path);
int len = 0;
while ((len = reader.read()) != -1) {
System.out.print((char) len);
}
reader.close();
}
}
2.輸出字元流
2.1 Writer
Writer中的常見的方法:
1) write(ch): 将一個字元寫入到流中。
2) write(char[]): 将一個字元數組寫入到流中。
3) write(String): 将一個字元串寫入到流中。
4) flush():重新整理流,将流中的資料重新整理到目的地中,流還存在。
5) close():關閉資源:在關閉前會先調用flush(),重新整理流中的資料去目的地。然流關閉。
發現基本方法和OutputStream 類似,有write方法,功能更多一些。可以接收字元串。
同樣道理Writer是抽象類無法建立對象。查閱API文檔,找到了Writer的子類FileWriter
1:将文本資料存儲到一個檔案中。
public class IoTest2_Writer {
public static void main(String[] args) throws Exception {
String path = "c:/ab.txt";
writeToFile(path);
}
/**
* 寫指定資料到指定檔案中
*
*/
public static void writeToFile(String path) throws Exception {
Writer writer = new FileWriter(path);
writer.write('中');
writer.write("世界".toCharArray());
writer.write("中國");
writer.close();
}
}
2:追加檔案:
預設的FileWriter方法新值會覆寫舊值,想要實作追加功能需要
使用如下構造函數建立輸出流 append值為true即可。
FileWriter(String fileName, boolean append)
FileWriter(File file, boolean append)
3:flush方法
如果使用字元輸出流,沒有調用close方法,會發生什麼?
private static void writeFileByWriter(File file) throws IOException {
FileWriter fw = new FileWriter(file);
fw.write('新');
fw.flush();
fw.write("中國".toCharArray());
fw.write("世界你好!!!".toCharArray());
fw.write("明天");
// 關閉流資源
//fw.close();
}
程式執行完畢打開檔案,發現沒有内容寫入.原來需要使用flush方法. 重新整理該流的緩沖。
為什麼隻要指定claose方法就不用再flush方法,因為close也調用了flush方法.
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
輸出字元流:
------| Writer 輸出字元流的基類。 抽象類
-----------| FileWriter 向檔案資料資料的輸出字元流
FileWriter的使用步驟:
1. 找到目标檔案。
2. 建立資料輸出通道
3. 寫出資料。
4. 關閉資源
FileWriter要注意的事項:
1. 使用FileWriter寫資料的時候,FileWriter内部是維護了一個1024個字元數組的,寫資料的時候會先寫入到它内部維護的字元數組中,如果需要
把資料真正寫到硬碟上,需要調用flush或者是close方法或者是填滿了内部的字元數組。
2. 使用FileWriter的時候,如果目标檔案不存在,那麼會自動建立目标檔案。
3.使用FileWriter的時候, 如果目标檔案已經存在了,那麼預設情況會先情況檔案中的資料,然後再寫入資料 , 如果需要在原來的基礎上追加資料,
需要使用“new FileWriter(File , boolean)”的構造方法,第二參數為true。
public class Demo1 {
public static void main(String[] args) throws IOException {
writeTest1();
}
public static void writeTest1() throws IOException{
//找到目标檔案
File file = new File("F:\\a.txt");
//建立資料輸出通道
FileWriter fileWriter = new FileWriter(file,true);
//準備資料,把資料寫出
String data = "今天天氣非常好!!";
fileWriter.write(data); //字元流具備解碼的功能。
//重新整理字元流
// fileWriter.flush();
//關閉資源
fileWriter.close();
}
}
3.字元流與位元組流拷貝檔案
練習: 使用字元流拷貝一個文本檔案(java檔案).
接着使用字元流拷貝一個圖檔(觀察圖檔的大小變化,思考為什麼會這樣子??)
何時使用字元流,何時使用位元組流?依據是什麼?
使用字元流的應用場景: 如果是讀寫字元資料的時候則使用字元流。
使用位元組流的應用場景: 如果讀寫的資料都不需要轉換成字元的時候,則使用位元組流。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//使用字元流拷貝檔案
public class Copy {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("F:\\Test.txt"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\Test.exe"));
String line=null;
while((line = bufferedReader.readLine())!=null){
bufferedWriter.write(line);
}
bufferedWriter.close();
bufferedReader.close();
}
}
使用位元組流讀取中文
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
//使用位元組流讀取中文
public class Demo2 {
public static void main(String[] args) throws IOException {
File file = new File("F:\\a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[1024];
int length = 0;
while((length = fileInputStream.read(buf))!=-1){
System.out.println(new String(buf,0,length)); //借用字元串的解碼功能。
}
}
}
4.緩沖輸入字元流
輸入字元流:
-------| Reader 所有輸入字元流的基類。 抽象類
----------| FileReader 讀取檔案字元串的輸入字元流。
----------|BufferedReader 緩沖輸入字元流 。 緩沖 輸入字元流出現的目的是為了提高讀取檔案 的效率和拓展了FileReader的功能。 其實該類内部也是維護了一個字元數組
記住:緩沖流都不具備讀寫檔案的能力。
BufferedReader的使用步驟:
1.找到目标檔案
2 .建立資料的輸入通道。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) throws IOException {
// readTest1();
File file = new File("F:\\ buffered\\Demo1.java");
//建立資料的輸入通道。
FileReader fileReader = new FileReader(file);
String line = null;
while((line = myReadLine(fileReader))!=null){
System.out.println(line);
}
}
//自己去實作readLine方法。
public static String myReadLine(FileReader fileReader) throws IOException{
//建立一個字元串緩沖類對象
StringBuilder sb = new StringBuilder(); //StringBuilder主要是用于存儲讀取到的資料
int content = 0 ;
while((content = fileReader.read())!=-1){
if(content=='\r'){
continue;
}else if(content=='\n'){
break;
}else{
//普通字元
sb.append((char)content);
}
}
//代表已經讀取完畢了。
if(content ==-1){
return null;
}
return sb.toString();
}
public static void readTest1() throws IOException{
//找到目标檔案
File file = new File("F:\\a.txt");
//建立資料的輸入通道。
FileReader fileReader = new FileReader(file);
//建立緩沖輸入字元流
BufferedReader bufferedReader = new BufferedReader(fileReader);
//讀取資料
/*int content = bufferedReader.read(); //讀到了一個字元。 讀取到的字元肯定也是從Bufferedreader内部的字元數組中擷取的到。是以效率高。
System.out.println((char)content);*/
//使用BUfferedReader拓展的功能,readLine() 一次讀取一行文本,如果讀到了檔案的末尾傳回null表示。
String line = null;
while((line = bufferedReader.readLine())!=null){ // 雖然readLine每次讀取一行資料,但是但會的line是不包含\r\n的、
System.out.println(Arrays.toString("aaa".getBytes()));
}
//關閉資源
bufferedReader.close();
}
}
5. 緩沖輸出字元流
輸出字元流
----------| Writer 所有輸出字元流的基類, 抽象類。
--------------- | FileWriter向檔案輸出字元資料的輸出字元流。
----------------|BufferedWriter 緩沖輸出字元流
緩沖輸出字元流作用: 提高FileWriter的寫資料效率與拓展FileWriter的功能。
BufferedWriter内部隻不過是提供了一個8192長度的字元數組作為緩沖區而已,拓展了FileWriter的功能。
BufferedWriter如何使用?
1. 找到目标檔案
2. 建立資料的輸出通道
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) throws IOException {
//找到目标檔案
File file = new File("F:\\a.txt");
//建立資料的輸出通道
FileWriter fileWriter = new FileWriter(file,true);
//建立緩沖輸出流對象
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
//寫出資料
// bufferedWriter.newLine(); //newLine() 換行。 實際上就是想檔案輸出\r\n.
bufferedWriter.write("\r\n");
bufferedWriter.write("前兩天李克強來蘿崗!!");
//關閉資源
bufferedWriter.flush();
// bufferedWriter.close();
}
}
6.緩沖輸入輸出字元流登入
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Login {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws IOException {
while (true) {
System.out.println("請選擇功能: A(注冊) B(登陸)");
String option = scanner.next();
if ("a".equalsIgnoreCase(option)) {
//注冊
reg();
} else if ("b".equalsIgnoreCase(option)) {
//登陸
login();
} else {
System.out.println("你的輸入有誤,請重新輸入...");
}
}
}
//登陸
public static void login() throws IOException {
System.out.println("請輸入使用者名:");
String userName = scanner.next();
System.out.println("請 輸入密碼:");
String password = scanner.next();
String info = userName + " " + password;
//讀取檔案的資訊,檢視是否有該使用者的資訊存在,如果存在則登陸成功。
//建立資料的輸入通道
//建立緩沖輸入字元流
BufferedReader bufferedReader = new BufferedReader(new FileReader(
"F:\\users.txt"));
String line = null;
boolean isLogin = false; // 用于記錄是否登陸成功的辨別, 預設是登陸失敗的。
//不斷的讀取檔案的内容
while ((line = bufferedReader.readLine()) != null) {
if (info.equals(line)) {
isLogin = true;
break;
}
}
if (isLogin) {
System.out.println("歡迎" + userName + "登陸成功...");
} else {
System.out.println("不存在該使用者資訊,請注冊!!");
}
}
//注冊
public static void reg() throws IOException {
System.out.println("請輸入使用者名:");
String userName = scanner.next();
System.out.println("請 輸入密碼:");
String password = scanner.next();
String info = userName + " " + password;
//把使用者的注冊的資訊寫到檔案上
File file = new File("F:\\users.txt");
FileWriter fileWriter = new FileWriter(file, true);
//建立緩沖輸出字元流
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
//把使用者資訊寫出
bufferedWriter.write(info);
bufferedWriter.newLine();
//關閉資源
bufferedWriter.close();
}
}
7.裝飾者模式1
裝飾者設計模式:增強一個類的功能,而且還可以讓這些裝飾類互相裝飾。
BufferedReader是不是拓展了FileReader的功能。
BuferedWriter 也是拓展了FileWriter的功能。
需求1: 編寫一個類拓展BufferedReader的功能,增強readLine方法傳回 的字元串帶有行号。
需求2:編寫一個類拓展BufferedReader的功能,增強readLine方法傳回 的字元串帶有分号。
需求3: 編寫一個類拓展BufferedReader的功能,增強readLine方法傳回 的字元串帶有雙引号。
需求4: 編寫一個類拓展BufferedReader的功能, 增強readLine方法傳回 的字元串帶有行号+ 分号。
需求5: 編寫一個類拓展BufferedReader的功能, 增強readLine方法傳回 的字元串帶有分号+ 雙引号。
需求6: 編寫一個類拓展BufferedReader的功能,增強readLine方法傳回 的字元串帶有雙引号+ 行号。
需求7: 編寫一個類拓展BufferedReader的功能, 增強readLine方法傳回 的字元串帶有行号+ 分号+雙引号。
----| Reader
-----------| BufferedReader
---------------|BufferedLineNum 帶行号
---------------|BufferedSemi 帶分号
---------------|BufferedQuto 帶雙引
---------------| 子類..
---------------|
增強一個類的功能時候我們可以選擇使用繼承:
通過繼承實作增強一個類的功能優點: 代碼結構清晰,通俗易懂。
缺點: 使用不靈活,會導緻繼承的體系過于龐大。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
class BufferedLineNum extends BufferedReader {
//行号
int count = 1;
public BufferedLineNum(Reader in) {
super(in);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line == null) {
return null;
}
line = count + " " + line;
count++;
return line;
}
}
//帶分号的緩沖輸入字元流
class BufferedSemi extends BufferedReader {
public BufferedSemi(Reader in) {
super(in);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line == null) {
return null;
}
line = line + ";";
return line;
}
}
//帶雙引号的緩沖輸入字元流
class BufferedQuto extends BufferedReader {
public BufferedQuto(Reader in) {
super(in);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line == null) {
return null;
}
line = "\"" + line + "\"";
return line;
}
}
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File("F:\\Demo1.java");
//建立資料的輸入通道
FileReader fileReader = new FileReader(file);
//建立帶行号的緩沖輸入字元流
BufferedLineNum bufferedLineNum = new BufferedLineNum(fileReader);
//帶有分号的緩沖輸入字元流
BufferedSemi bufferedSemi = new BufferedSemi(fileReader);
//帶有雙引号的緩沖輸入字元流
BufferedQuto bufferedQuto = new BufferedQuto(fileReader);
String line = null;
while ((line = bufferedQuto.readLine()) != null) {
System.out.println(line);
}
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
/*
裝飾者設計模式:增強一個類的功能,而且還可以讓這些裝飾類互相裝飾。
裝飾者設計模式的步驟:
1. 在裝飾類的内部維護一個被裝飾類的引用。
2. 讓裝飾類有一個共同的父類或者是父接口。
繼承實作的增強類和修飾模式實作的增強類有何差別?
繼承實作的增強類:
優點:代碼結構清晰,而且實作簡單.
缺點:對于每一個的需要增強的類都要建立具體的子類來幫助其增強,這樣會導緻繼承體系過于龐大。
修飾模式實作的增強類:
優點:内部可以通過多态技術對多個需要增強的類進行增強, 可以是這些裝飾類達到互相裝飾的效果。使用比較靈活。
缺點:需要内部通過多态技術維護需要被增強的類的執行個體。進而使得代碼稍微複雜。
*/
import java.io.IOException;
//帶行号的緩沖輸入字元流
class BufferedLineNum2 extends BufferedReader {
//在内部維護一個被裝飾類的引用。
BufferedReader bufferedReader;
int count = 1;
public BufferedLineNum2(BufferedReader bufferedReader) {
super(bufferedReader); // 注意: 該語句沒有任何的作用,隻不過是為了讓代碼不報錯。
this.bufferedReader = bufferedReader;
}
public String readLine() throws IOException {
String line = bufferedReader.readLine();
if (line == null) {
return null;
}
line = count + " " + line;
count++;
return line;
}
}
//帶分号緩沖輸入字元流
class BufferedSemi2 extends BufferedReader { //為什麼要繼承? 是為了讓這些裝飾類的對象可以作為參數進行傳遞,達到互相裝飾 的效果。
//在内部維護一個被裝飾類的引用。
BufferedReader bufferedReader;
public BufferedSemi2(BufferedReader bufferedReader) { // new BuffereLineNum();
super(bufferedReader); // 注意: 該語句沒有任何的作用,隻不過是為了讓代碼不報錯。
this.bufferedReader = bufferedReader;
}
public String readLine() throws IOException {
String line = bufferedReader.readLine(); //如果這裡的ReadLine方法是調用了buffereLineNum的readLine方法,問題馬上解決。
if (line == null) {
return null;
}
line = line + ";";
return line;
}
}
//緩沖類帶雙引号
class BufferedQuto2 extends BufferedReader {
//在内部維護一個被裝飾的類
BufferedReader bufferedReader;
public BufferedQuto2(BufferedReader bufferedReader) { //new BufferedSemi2();
super(bufferedReader); //隻是為了讓代碼不報錯..
this.bufferedReader = bufferedReader;
}
public String readLine() throws IOException {
String line = bufferedReader.readLine(); //如果這裡的ReadLine方法是調用了buffereLineNum的readLine方法,問題馬上解決。
if (line == null) {
return null;
}
line = "\"" + line + "\"";
return line;
}
}
public class Demo2 {
public static void main(String[] args) throws IOException {
File file = new File("F:\\Demo1.java");
FileReader fileReader = new FileReader(file);
//建立緩沖輸入字元流
BufferedReader bufferedReader = new BufferedReader(fileReader);
//建立帶行号的緩沖輸入字元流
BufferedLineNum2 bufferedLineNum = new BufferedLineNum2(bufferedReader);
//帶分号的緩沖輸入字元流
BufferedSemi2 bufferedSemi2 = new BufferedSemi2(bufferedLineNum);
//帶雙引号的緩沖輸入字元流
BufferedQuto2 bufferedQuto2 = new BufferedQuto2(bufferedSemi2);
String line = null;
while ((line = bufferedQuto2.readLine()) != null) {
System.out.println(line);
}
}
}
8. 裝飾者設計模式的作業
一家三口每個人都會工作,兒子的工作就是畫畫,母親的工作就是在兒子的基礎上做一個增強,不單止可以畫畫,還可以上塗料。
爸爸的工作就是在媽媽基礎上做了增強,就是上畫框。
interface Work {
public void work();
}
class Son implements Work {
@Override
public void work() {
System.out.println("畫畫...");
}
}
class Mather implements Work {
//需要被增強的類。
Work worker;
public Mather(Work worker) {
this.worker = worker;
}
@Override
public void work() {
worker.work();
System.out.println("給畫上顔色..");
}
}
class Father implements Work {
//需要被增強的類的引用
Work worker;
public Father(Work worker) {
this.worker = worker;
}
@Override
public void work() {
worker.work();
System.out.println("上畫框...");
}
}
public class Demo3 {
public static void main(String[] args) {
Son s = new Son();
// s.work();
Mather m = new Mather(s);
// m.work();
Father f = new Father(s);
f.work();
}
}