JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片
JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片
一.装饰设计模式
其实我们自定义readLine就是一种装饰模式
- 当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,并且提供加强功能,那么自定义的该类就称为装饰类
package com.lgl.hellojava;
public class HelloJJAVA {
public static void main(String[] args) {
Person p = new Person();
p.eat();
// 开始进行增强
superPerson p1 = new superPerson(p);
p1.superEat();
}
}
class Person {
public void eat() {
System.out.println("吃饭");
}
}
class superPerson {
private Person p;
public superPerson(Person p) {
this.p = p;
}
public void superEat() {
System.out.println("小菜+吃饭");
}
}
这里的逻辑就是当我们吃饭这个功能需要增强的时候,我们应该装饰他
- 装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能提供更强的功能
二.继承和装饰的区别
你现在知道了装饰模式,那你一定会疑问,和继承的道理类似,对吧,我们现在来说下他们的区别
这里我们就不写代码了,我们看注释
package com.lgl.hellojava;
public class HelloJJAVA {
public static void main(String[] args) {
/**
* MyReader:专门用于读取数据的类
* MyTextReader:专门读取文本 两个向上抽取,形成继承体系
*/
/**
* 想实现更多的功能
* MyBufferReader
* myBufferTestReader
*/
/**
*谁需要加强就传谁进来
* class MyBufferReader{
* }
*/
}
}
这个逻辑大概是这样的,我们有两个功能,一个读取文件,一个读取文本,他们其实是有共性的,你就把他们共性部分抽取出来,可是我现在在读取文本的时候我顺便想读取图片呢?其实,我们就是这样才产生的装饰者模式
- 装饰者模式比继承要灵活,避免了继承体系的臃肿,而且降低了类与类之间的关系
- 装饰类因为增强已有对象,具备功能和已有的想相同,只不过提供了更强的功能,所以装饰类和被装饰类通常属于一个体系中的
三.LineNumberReader
这也是一个子类
他也是一个包装类,我们看例子
package com.lgl.hellojava;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
public class HelloJJAVA {
public static void main(String[] args) {
FileReader fr;
try {
fr = new FileReader("test.txt");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
while((line = lnr.readLine()) != null){
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
他输出的结果
他可以获取和设置行号
四.自定义LineNumberReader
我们可以根据他的原理自己也来实现一个,仔细看注释
package com.lgl.hellojava;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class HelloJJAVA {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("test.txt");
MyLineNumberReader my = new MyLineNumberReader(fr);
String line = null;
while ((line = my.MyReadLine()) != null) {
System.out.println(my.getLineReader() + ":" + line);
}
my.MyClose();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyLineNumberReader {
// 读取
private Reader r;
// 行号
private int lineReader;
// 构造方法
public MyLineNumberReader(Reader r) {
this.r = r;
}
// 提供对外方法
public String MyReadLine() {
// 行号自增
lineReader++;
StringBuilder sb = new StringBuilder();
int ch = 0;
try {
while ((ch = r.read()) != -1) {
if (ch == '\r')
continue;
if (ch == '\n')
return sb.toString();
else
sb.append((char) ch);
}
if (sb.length() != 0)
return sb.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public int getLineReader() {
return lineReader;
}
public void setLineReader(int lineReader) {
this.lineReader = lineReader;
}
public void MyClose() {
try {
r.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这个思路是不是很清晰,实际上和LineNumberReader是类似的
五.字节流读取操作
字符流我们讲的差不多了,我们接着说字节,其实他们类似的,知识他操作的是字节而已
- inputStream:读
- outputStream:写
我们还是从例子开始
package com.lgl.hellojava;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class HelloJJAVA {
public static void main(String[] args) {
writeFile();
}
// 写文件
public static void writeFile() {
try {
FileOutputStream fo = new FileOutputStream("demo.txt");
fo.write("test".getBytes());
fo.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里我们可以看到,他写入数据不需要刷新,现在还没有涉及到缓存区,我们继续看,写已经写好了,现在我们开始读,对于读取数据,我们开头用到的两种方法
// 字符读数据
public static void readFile() {
try {
FileInputStream fs = new FileInputStream("demo.txt");
int ch = 0;
while ((ch = fs.read()) != -1) {
System.out.println((char) ch);
}
fs.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 字节读取
public static void readFile1() {
try {
FileInputStream fs = new FileInputStream("demo.txt");
byte[] buf = new byte[1024];
int len = 0;
while ((len = fs.read(buf)) != -1) {
System.out.println(new String(buf, 0, len));
}
fs.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
现在我们有了专门处理的字节流,我们可以这样做
public static void readFile2() {
try {
FileInputStream fs = new FileInputStream("demo.txt");
int num = fs.available();
System.out.println(num);
fs.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我们发现直接用available就可以拿到字节了,原理其实是这段代码
public static void readFile2() {
try {
FileInputStream fs = new FileInputStream("demo.txt");
byte[] buf = new byte[fs.available()];
fs.read(buf);
System.out.println(new String(buf));
fs.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
六.I/O复制图片
ok,这里算是一个小练习,复制一张图片,我们理顺下思路
- 1.用字节读取流和图片关联
- 2.用字节流写入流对象创建一个图片文件,存储数据
- 3.通过循环读写,完成数据存储
- 4.关闭流
OK,我们用代码说话
package com.lgl.hellojava;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class HelloJJAVA {
public static void main(String[] args) {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
// 复制
fos = new FileOutputStream("copy_img.png");
// 原图
fis = new FileInputStream("img.png");
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这样。我们图片就拷贝过来了
好的,知识点今天就到这里
有兴趣的可以加群:555974449,咱们一起学习,一起进步!
JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片的更多相关文章
- JAVA之旅(十六)——String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较
JAVA之旅(十六)--String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较 过节耽误了几天,我们继续JAVA之旅 一.String概述 String时 ...
- Java进阶专题(二十六) 将近2万字的Dubbo原理解析,彻底搞懂dubbo
前言 前面我们研究了RPC的原理,市面上有很多基于RPC思想实现的框架,比如有Dubbo.今天就从Dubbo的SPI机制.服务注册与发现源码及网络通信过程去深入剖析下Dubbo. Dubbo架构 ...
- Java开发学习(二十六)----SpringMVC返回响应结果
SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...
- Java从零开始学二十六(包装类)
一.包装类 包装类是将基本类型封装到一个类中.也就是将基本数据类型包装成一个类类型. java程序设计为每一种基本类型都提供了一个包装类.这些包装类就在java.lang包中.有8个包装类 二.包装类 ...
- Java基础(二十六)Java IO(3)字节流(Byte Stream)
字节流是以字节为单位来处理数据的,由于字节流不会对数据进行任何转换,因此用来处理二进制的数据. 一.InputStream类与OutputStream类 1.InputStream类是所有字节输入流的 ...
- Java之集合(二十六)ConcurrentSkipListMap
转载请注明源出处:http://www.cnblogs.com/lighten/p/7542578.html 1.前言 一个可伸缩的并发实现,这个map实现了排序功能,默认使用的是对象自身的compa ...
- Java学习笔记二十六:Java多态中的引用类型转换
Java多态中的引用类型转换 引用类型转换: 1.向上类型转换(隐式/自动类型转换),是小类型到大类型的转换: 2.向下类型转换(强制类型转换),是大类型到小类型的转换: 3.instanceof运算 ...
- Python学习日记(二十六) 封装和几个装饰器函数
封装 广义上的封装,它其实是一种面向对象的思想,它能够保护代码;狭义上的封装是面向对象三大特性之一,能把属性和方法都藏起来不让人看见 私有属性 私有属性表示方式即在一个属性名前加上两个双下划线 cla ...
- java 面向对象(二十六):枚举类的使用
1. 枚举类的说明:* 1.枚举类的理解:类的对象只有有限个,确定的.我们称此类为枚举类* 2.当需要定义一组常量时,强烈建议使用枚举类* 3.如果枚举类中只一个对象,则可以作为单例模式的实现方式. ...
- Java进阶专题(二十六) 数据库原理研究与优化
前言 在一个大数据量的系统中,这些数据的存储.处理.搜索是一个非常棘手的问题. 比如存储问题:单台服务器的存储能力及数据处理能力都是有限的, 因此需要增加服务器, 搭建集群来存储海量数据. 读写性能问 ...
随机推荐
- IP地址、子网掩码、网关、DNS服务器
1. IP地址 IP是英文Internet Protocol的缩写,意思是"网络之间互连的协议",也就是为计算机网络相互连接进行通信而设计的协议.在因特网中,它是能使连接到网上的所 ...
- Python中模块之sys的功能介绍
sys模块的功能介绍 1. sys的变量 argv 命令行参数 方法:sys.argv 返回值:list 例如:test1.py文件中有两句语句1.import sys 2.print(sys.arg ...
- Java8-理解Colloctor
上一节学习了Java8中比较常用的内置collector的用法.接下来就来理解下collector的组成. Collector定义 Collector接口包含了一系列方法,为实现具体的归约操作(即收集 ...
- python2.7练习小例子(二)
2):题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:2 ...
- 在confluence中出现Handshake failed due to invalid Upgrade header: null
在confluence中出现Handshake failed due to invalid Upgrade header: null 昨天晚上同事说confluence写完日志保存不了,然后我登陆co ...
- 干货满满,腾讯云+社区技术沙龙 Kafka Meetup 深圳站圆满结束
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 云+导语:4月22日,由腾讯云和 Kafka 社区主办.开源中国协办的腾讯云+社区技术沙龙 Kafka Meetup 深圳站在腾讯大厦举行, ...
- spring的 @Scheduled的cron表达式
网上太多说的多,但却没什么用的文章了 序号 说明 是否必填 允许填写的值 允许的通配符1 秒 是 0-59 , ...
- 关于一些基础的Java问题的解答(六)
26. ThreadPool用法与优势 ThreadPool即线程池,它是JDK1.5引入的Concurrent包中用于处理并发编程的工具.使用线程池有如下好处: 降低资源消耗:通过重复利用已创建的线 ...
- Mysql数据库连接报错!1130:host XXX is not allowed to connect to this mysql server
我猜想是可能是连接的用户权限问题.结果这样子操作mysql库,可以解决此问题.在本机登入mysql后,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,从”localhost” ...
- 【转载】给想要入门渗透的人的忠告——schiz0wcingU
最近发现很多拥有黑客梦想的年轻人在群里或者论坛里,找"师傅"或者学一些所谓的"社工" 这些找师傅的人当中,有极大一部分人是还在上学的学生,自然也就没有收入来源, ...