java学习(13)
设 计 模式。这篇接着上篇来写IO流,上篇写了关于字节流,这篇主要来写字符流以及一些
1.字符流,上篇已经提到了IO流的数据分类,即字节流和字符流
字符流:
Reader
Writer
1.1 IO流中的编码和解码问题
1)OutputStreamWriter:把字节输出流转换为字符输出流
2)InputStreamReader:把字节输入流转换为字符输入流
1.2 转换流
A.写入数据,把字节输出流转换为字符输出流(不指定码表)
//写入数据,把字节输出流转换为字符输出流(不指定码表)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("H://a.txt"));
osw.write("helloworld");
osw.flush();//刷新缓冲区
osw.close();
B.把字节输出流转换为字符输出流(指定码表)
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("H://b.txt"),"utf-8");
osw2.write("good!");
osw2.flush();//刷新缓冲区
osw2.close();//关流
C.读取数据, 把字节输入流转换为字符输入流(不指定码表)
InputStreamReader isr = new InputStreamReader(new FileInputStream("H://a.txt"));
int ch;
while ((ch=isr.read())!=-1) {
System.out.println((char)ch);
}
//关流
isr.close();
D.把字节输入流转换为字符输入流(指定码表)
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("H://b.txt"),"utf-8");
int ch2;
while ((ch2=isr2.read())!=-1) {
System.out.println((char)ch2);
}
//关流
isr2.close();
总结:一般创建字符输入或者输出流一般情况下使用系统默认的码表,一直来指定码表进行读写太过于麻烦。
1.3简化上面的方式
如果采用刚才的方式,创建对象写起来比较复杂。
为了简化这种操作,java就针对这两个转换的字符流提供其子类。
A. FileReader
B. FileWriter
默认编码是采用系统编码:
构造方法:
A. FileWriter(File file)
B. FileWriter(String fileName)
C. FileReader(File file)
D. FileReader(String fileName)
1.4给字符输出流里面利用方法写数据
字符输出流操作步骤:
A:创建字符输出流对象
B:调用写数据方法
C:释放资源
写数据方法:
A.一次写一个字符 write(int c)
B.一次写一个字符数组write(char[] cbuf)
C.一次写一个字符数组的一部分write(char[] cbuf, int off,int len)
D.一次写一个字符串write(String str)
E.一次写一个字符串的一部分write(String str,int off,int len)
代码示例:
public static void main(String[] args) throws IOException {
//字符输出流操作步骤:
//A:创建字符输出流对象
FileWriter fw = new FileWriter("H://a.txt");
//B:调用写数据方法
//写数据方法:
//一次写一个字符 write(int c)
fw.write(65);
fw.flush();
//一次写一个字符数组write(char[] cbuf)
char[] chs = {'1','b','c'};
fw.write(chs);
fw.flush();
//一次写一个字符数组的一部分write(char[] cbuf, int off,int len)
char[] chs2 = {'2','d','e'};
fw.write(chs2, 0, 2);
fw.flush();
//一次写一个字符串write(String str)
String str = "3fg";
fw.write(str);
fw.flush();
//一次写一个字符串的一部分write(String str,int off,int len)
String str2 = "4hijklmn";
fw.write(str2,0,3);
fw.flush();
//C:释放资源
fw.close();
}
结果:
1.5 字符输入流,和字符输出流类似:
字符输入流操作步骤:
A:创建字符输入流对象:
B:读取数据并显示在控制台
a:一次读取一个字符
b:一次读取一个字符数组
C:释放资源
代码示例:
public static void main(String[] args) throws IOException {
//字符输入流操作步骤:
//A:创建字符输入流对象
FileReader fr = new FileReader("H://a.txt");
//B:读取数据并显示在控制台
//a:一次读取一个字符
//一次读取一个字符
int ch;
while ((ch = fr.read()) != -1) {
System.out.print((char) ch);
}
System.out.println();
System.out.println("===========");
FileReader fr2 = new FileReader("H://a.txt");
//b:一次读取一个字符数组
char[] chs = new char[1024];
int len;
while ((len = fr2.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
//C:释放资源
fr.close();
fr2.close();
}
结果:1.6 注意:字符流输入输出流复制的文件是有要求的,简单来说只要是记事本打开文件的内容你能够看得懂,就可以用字符流来进行复制,否则不行
具体原因:像复制MP3或者一些视频文件的时候,如果他的字节个数不是偶数的话,就会造成文件的缺损,因为一个字符等于两个字节
1.7 高效流,字符流的高效流,类似于字节流的高效流,都是抽象类,但是字符流的高效流有特殊的方法,比较实用:
1)BufferedReader:字符缓冲输入流
构造:BufferedReader(Reader in)
特殊方法:public String readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
2)BufferedWriter:字符缓冲输出流
构造:BufferedWriter(Writer out)
特殊方法:public void newLine():会根据系统来确定写入不同的换行符
代码示例:利用BufferedWriter的newLine()方法实现换行输入,这可以让同一个代码在不同平台下运行;否则不同平台下,换行符可能是不同的,要修改代码。
public static void main(String[] args) throws IOException {
//给文件中写入十个"helloworld",每写一个换一行,每写一行必须写入一个换行符“/r/n”
//BufferedWriter:字符缓冲输出流
//构造:BufferedWriter(Writer out)
//特殊方法:public void newLine():会根据系统来确定写入不同的换行符
//1.创建字符高效输出流,并指向一个txt文件
BufferedWriter bw = new BufferedWriter(new FileWriter("H://a.txt"));
for (int i = 0; i < 10; i++) {
//2.调用里面写数据的方法,给文件中写入数据
bw.write("helloworld!");
//3.调用换行的方法,给写入的数据换行
bw.newLine();
//4.刷新换新区
bw.flush();
}
//5.关流
bw.close();
}
结果:
代码示例:利用BufferedReader的readLine()方法可以换行读取数据
public static void main(String[] args) throws IOException {
//读取a.txt文件
//1.创建高效字符输入流对象
BufferedReader br = new BufferedReader(new FileReader("H://a.txt"));
// 2.一次读取一行,readLine()
String line;
while((line=br.readLine())!=null){
System.out.println(line);
}
//3.关流
br.close();
}
2.设计模式
2.1A:设计模式概述1)设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
2)使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性以及代码的结构更加清晰.
2.2B:设计模式分类
(1)创建型模式(创建对象的):单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
(2)行为型模式(对象的功能):适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
(3)结构型模式(对象的组成):模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
2.3 设计模式很多,这里主要分析一下单例设计模式和工厂设计模式
2.3.1单例设计模式:
A.单例设计思想
保证类在内存中只有一个对象
B:实现
1)构造私有
2)本身提供一个对象
3)通过公共的方法让外界访问
C.分类
1)饿汉式:当这个类一被加载,就在内存中创建了一个对象
2)懒汉式:需要的时候才去创建对象,不需要的时候不创建
示例:这里给出一个饿汉式的代码示例
public class SingleInstanceTest01 {
/**
* 饿汉式:当这个类一被加载,就在内存中创建了一个对象
* 1.保证内存中只有一个对象(构造私有)
* 2.在本类中创建一个该类的对象
* 3.创建一个公共的访问方式给外界获取该对象
*/
//1.保证内存中只有一个对象(构造私有)
private SingleInstanceTest01(){};
//2.在本类中创建一个该类的对象
private static SingleInstanceTest01 sit= new SingleInstanceTest01();
//3.创建一个公共的访问方式给外界获取该对象
public static SingleInstanceTest01 method(){
return sit;
}
}
public class SingleInstanceTest01_test {
public static void main(String[] args) {
SingleInstanceTest01 test = SingleInstanceTest01.method();
SingleInstanceTest01 test2 = SingleInstanceTest01.method();
//是一个对象为true,否则为false
System.out.println(test.equals(test2));
}
}
分析:得出的结果为true,在test类里面的两个对象是同一个对象,即在SingleInstanceTest01类里面提供的对象。2.3.2 工厂设计模式
简单工厂模式:
责创建一些类的实例A:简单工厂模式概述: 又叫静态工厂方法模式,它定义一个具体的工厂类负
类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品。即:明确了类的职责B:优点: 使用静态工厂模式的优点是实现责任的分割,该模式的核心是工厂
些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护C:缺点: 这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某
抽象工厂模式:
A:工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
B:优点: 客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
C:缺点: 需要额外的编写代码,增加了工作量
示例:这里给出一个简单工厂的设计模式代码,创建了一个Person父类,和两个子类Student和Teacher,通过PersonFactory类来创建对象
public abstract class Person {
public abstract void work();
}
public class Student extends Person{
@Override
public void work() {
System.out.println("学生的工作是学习!");
}
}
public class Teacher extends Person{
@Override
public void work() {
System.out.println("老师的工作是教学生!");
}
}
public class PersonFactory {
public static Person getPerson(String type){
if("Student".equals(type)){
return new Student();
}else if("Teacher".equals(type)){
return new Teacher();
}
return null;
}
}
public class Test {
public static void main(String[] args) {
//通过PersonFactory类创建对象
Person s = PersonFactory.getPerson("Student");
s.work();
Person t = PersonFactory.getPerson("Teacher");
t.work();
}
}
结果: