极力推荐阅读:https://blog.csdn.net/baidu_37107022/article/details/76890019
1、装饰设计模式和IO流
装饰设计模式
*1. 抽象组件:需要装饰的抽象对象(接口或抽象父类)
*2. 具体组件:需要装饰的对象
*3. 抽象装饰类: 包含了对抽象组件的引用以及装饰者共有的方法
*4. 具体装饰类: 被装饰的对象
import java.io.BufferedInputStream;
import java.io.InputStream;
/**
*0 装饰器设计模式
*1. 抽象组件:需要装饰的抽象对象(接口或抽象父类) InputStream
*2. 具体组件:需要装饰的对象 FileInputStream ByteArrayInputStream
*3. 抽象装饰类: 包含了对抽象组件的引用以及装饰者共有的方法 FileInputStream
*4. 具体装饰类: 被装饰的对象 BufferedInputStream ObjectInputStream DataInputStream
*
* @author 24322
*
*/
public class Test01 {
public static void main(String[] args) {
Drink coffee = new Coffee();
System.out.println(coffee.info()+":"+coffee.cost());
Decorate milk = new Milk(coffee);
System.out.println(milk.info()+":"+milk.cost());
Decorate suger = new Suger(milk);
System.out.println(suger.info()+":"+suger.cost());
}
}
// 抽象组件
interface Drink{
double cost();// 价格
String info();// 说明
}
// 具体组件
class Coffee implements Drink{
private String name = "原味咖啡";
@Override
public double cost() {
return 10;
}
@Override
public String info() {
return name;
}
}
// 抽象装饰类
abstract class Decorate implements Drink{
// 对抽象组件的引用
private Drink drink;
public Decorate(Drink drink) {
this.drink = drink;
}
@Override
public double cost() {
return this.drink.cost();
}
@Override
public String info() {
return this.drink.info();
}
}
// 具体装饰类
class Milk extends Decorate{
public Milk(Drink drink) {
super(drink);
}
@Override
public double cost() {
return super.cost()*4;
}
@Override
public String info() {
return super.info()+"加入了牛奶";
}
}
//具体装饰类
class Suger extends Decorate{
public Suger(Drink drink) {
super(drink);
}
@Override
public double cost() {
return super.cost()*2;
}
@Override
public String info() {
return super.info()+"加入了蔗糖";
}
}
2、装饰流
2.1 字节缓冲流
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* 加入缓冲流
* @author 24322
*
*/
public class Test02 {
public static void main(String[] args) {
//1、 创建源
File src = new File("123.txt");
//2、选择流
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(src)) ;
//3、操作:分段读取
byte[] flush = new byte[1024];
int len = -1;
while ((len = in.read(flush))!=-1) {
String str = new String(flush,0,len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//4、释放资源
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.2 字符缓冲流
BufferedReader提供的新方法(所以不能用多态)
BufferedWriter提供的新方法
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* 将字节流转换成字符流
* @author 24322
*
*/
public class Test03 {
public static void main(String[] args) {
System.out.println("Hello");
//操作System.in 和 System.out
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));){
// 循环获取键盘输入,输出此内容
String msg = "";
while (!msg.equals("exit")) {
msg = reader.readLine();//循环读取
writer.write(msg);//循环写出
writer.newLine();
writer.flush();// 强制刷新
}
} catch (IOException e) {
System.out.println("操作异常");
}
}
}
2.3 转换流
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的
将要写入流中的字符编码成字节。charset
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的
读取字节并将其解码为字符。charset
转换流的两个作用
1. 将字节流转换成字符流
2. 指定字符集
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* 将字节流转换成字符流
* @author 24322
*
*/
public class Test03 {
public static void main(String[] args) {
System.out.println("Hello");
//操作System.in 和 System.out
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));){
// 循环获取键盘输入,输出此内容
String msg = "";
while (!msg.equals("exit")) {
msg = reader.readLine();//循环读取
writer.write(msg);//循环写出
writer.newLine();
writer.flush();// 强制刷新
}
} catch (IOException e) {
System.out.println("操作异常");
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
/**
* 指定字符集
* @author 24322
*
*/
public class Test04 {
public static void main(String[] args) {
// 下载百度的源代码
try(BufferedReader reader =
new BufferedReader( // 缓冲流
new InputStreamReader( // 转换为字符流,设置字符集
new URL("https://www.baidu.com").openStream(),"UTF-8"));){
String string="";
while ((string=reader.readLine())!=null) {
System.out.print(string);
}
}catch (IOException e) {
System.out.println("操作异常");
}
}
}
造成乱码可能的两个原因:
1. 字节数不够
2.字符集不统一
2.4 数据流
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* 先写出后读取
* 读取和写出的顺序保持一致
* @author 24322
*
*/
public class Test05 {
public static void main(String[] args) throws IOException {
//写出
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
dos.writeUTF("编码");
dos.writeInt(18);
dos.writeBoolean(true);
byte[] datas = baos.toByteArray();
//读取
DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
String msg = dis.readUTF();
int age = dis.readInt();
boolean flag = dis.readBoolean();
System.out.println(msg);
System.out.println(age);
System.out.println(flag);
}
}
2.5 对象流
序列化和反序列化
1.先写出后读取
2. 读取和写入顺序一样
3. 只有实现了Serializable接口的类的对象才能序列化
使用方法和DataInputStream类似