1 Buffered修饰器模式
1.1 修饰器模式
- 什么是修饰器模式?
例如:
BufferedReader是Reader的子类,它具有一个属性Reader,因此可以将一个Reader的子类流对象传入BufferedReader,可以通过增加缓冲的方式提供性能。
对应Write也是同样的,再通过方法对流的功能进行包装,这种设计模式叫修饰器模式。
1.2 BufferedReader\BufferedWriter
BufferedReader\BufferedWriter是Buffered修饰的字符处理流。
public class Demo01 {
public static void main(String[] args) throws Exception {
String filePath = "e:/a.txt";
String endPath = "e:/c.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//将FileReader用BufferedReader修饰
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(endPath));
//将FileWriter用BufferedWriter修饰
String line;//按行读取
while ((line = bufferedReader.readLine())!=null){//readLine方法是按行读取,读取完毕后返回空
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedReader.close();//BufferedReader的close方法,会判断传入的流是否为空,不为空会关闭传入的流
bufferedWriter.close();//BufferedReader的close方法,会判断传入的流是否为空,不为空会关闭传入的流
}
}
1.3 BufferedInputStream\BufferedOutputStream
BufferedInputStream\BufferedOutputStream是Buffered修饰的字节处理流。
public class Demo02 {
public static void main(String[] args) {
String filePath = "e:/licen.jpg";
String endPath = "e:/licencopy.jpg";
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(filePath));
out = new BufferedOutputStream(new FileOutputStream(endPath));
byte[] bfin = new byte[1024];
int read = 0;
while ((read = in.read(bfin))!=-1){
out.write(bfin,0,read);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
2. 对象流
- 将基本数据类型或对象进行序列化和反序列化操作
- 1.序列化:在保存数据时,保存数据的值和数据类型
- 2.反序列化:在恢复数据时,恢复数据的值和数据类型
- 3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,这要求实现两个接口之一:
- Serializable//标记接口,它没有任何方法
- Externalizable//也是实现了Serializable接口,但具有一些方法
对象流也是应用了修饰器模式,或者说处理流都是应用了修饰器模式
2.1 ObjectInputStream/ObjectOutputStream
ObjectOutputStream 提供反序列化
public class Demo03 {
public static void main(String[] args) throws IOException {
String filePath = "e:/data.dat";//序列化后,保存的文件格式不是文本
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
objectOutputStream.writeInt(100);//int自动装箱Integer(实现了Serializable)
objectOutputStream.writeUTF("要吃大西瓜");//int自动装箱Integer(实现了Serializable)
objectOutputStream.writeObject(new Pig("邹邹",18));//int自动装箱Integer(实现了Serializable)
objectOutputStream.close();
}
}
class Pig implements Serializable{
private String name;
private int age;
public Pig(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Pig{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
ObjectInputStream 提供序列化
public class Demo04 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "e:\\data.dat";
ObjectInputStream out = new ObjectInputStream(new FileInputStream(filePath));
//反序列化的顺序需要和序列化的顺序一致
System.out.println(out.readInt());
System.out.println(out.readUTF());
Object pig = out.readObject();//读取对象会在底层转型为具体的类,会抛出异常
System.out.println(pig.getClass());
System.out.println(pig);
out.close();//同Buffered
}
}
- 1.反序列化的顺序和序列化的顺序必须一致,这里我序列化用了write(100),反序列化我使用了readInt(),结果报错,在序列化时使用writeInt(100)解决。
- 2.要求序列化或反序列化对象实现Serializable或Externalizable接口。
- 3.序列化对象时,默认将里面所有属性进行序列化,但除了static或transient修饰的成员。
- 4.序列化对象时,要求里面的属性的类型也需要实现序列化接口,才能被序列化。
- 5.序列化具备可继承性,也就是如果某类已经实现序列化,则它的所有子类也默认实现了序列化。
3. 标准输入输出流
- System.in 标准输入(键盘)
编译类型:InputStrem
运行类型:BufferedInputStream - System.out 标准输出(显示器)
编译类型:PrintStream
运行类型:PrintStream
4.转换流
转换字节类和字符流
- InputStreamReader:可以传入InputStream子类对象,将字节流转换成字符流,可以指定处理的编码
public class Demo05 {
public static void main(String[] args) throws Exception {
String filePath = "e:/a.txt";
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath),"UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String read;
while ((read = bufferedReader.readLine())!=null){
System.out.println(read);
}
bufferedReader.close();
}
}
- OutPutStreamWriter:可以传入OutputStream子类对象,将字节流转换成字符流,可以指定处理的编码
使用方法同InputStreamReader
5.打印流
只有输出流,没有输入流
PrintStream是FileOutputStream的子类,它是字节流,默认的输出位置是显示器。
PrintWriter是Writer的子类,它是字符流。
public class Demo06 {
public static void main(String[] args) throws IOException {
PrintStream out =System.out;
out.print("hi,lucky");
out.write("你好,确幸".getBytes());
System.setOut(new PrintStream("e:\\d.txt"));
System.out.println("n1c4n");
out.close();
}
}
6. Properties类
配置文件读写类
- 1.要求配置文件的格式:
键=值
键=值
…
键=值 - 2.Properties的常用方法
load:加载配置文件的键值对到Properties对象
list:将数据显示到指定设备
getProperty(key):根据键获取值
setProperty(key,value):设置键值对到Properties对象
store:将Properties中的键值对储存到配置文件,在idea中,保存到配置文件,字节流如果含有中文,会存储为unicode码 - 将properties123配置文件读取
/*
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//创建对象
Properties properties = new Properties();
//加载指定文件
properties.load(new FileReader("src\\properties123"));
//输出k-v
properties.list(System.out);
//根据key 获取对应的值
String name = (String) properties.get("name");
System.out.println(name);
}
}
- 使用Properties创建配置文件或修改配置文件
public class Demo02 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.setProperty("charset","UTF-8");
properties.setProperty("user","n1c4n");
properties.setProperty("key","123456789");
//将k-v 存储文件
properties.store(new FileWriter("e:\\properties321"),null);
//null为comments,可以为配置文件添加注释
properties.setProperty("key","987654321");
//setProperty()方法,当key不存在时,为创建,存在时,会修改
}
}