首页 > 代码库 > JAVA学习第四十九课 — IO流(三):缓冲区2 & 装饰设计模式
JAVA学习第四十九课 — IO流(三):缓冲区2 & 装饰设计模式
一、模拟BufferedReader
自定义MyBuffereaReader
对于缓冲区而言,里面其实就是封装一个数组,对外提供方法对数组的操作,这些方法最终操作的都是数组的角标
原理:从源中取出数据存入缓冲区,再从缓冲区不断的取出数据,取完后,继续从源中继续取数据,进缓冲区,直至源中的数据取完,用-1做为结束标记
import java.io.*; class MyBufferedReader { private FileReader fr; //定义数组作为缓冲区 private char[] ch = new char[1024]; //定义一个指针用于对数组的操作,当操作数组的最后一个元素后,指针归零 private int pos = 0; //定义一个计数器,当缓冲区的数据减至0后,继续从源中取数据加到缓冲区中 private int count = 0; MyBufferedReader(FileReader fr) { this.fr = fr; } public int Myread() throws IOException{ //从源中获取一批数据到缓冲区中,先判断count是否是0 if(count==0) { count = fr.read(ch); pos = 0; } if (count<0) return -1; char temp = ch[pos++]; count--; return temp; } public String MyReadLine() throws IOException{ //将读取的数据存储到缓冲区中 StringBuilder sb = new StringBuilder(); int ch = 0; while((ch = Myread())!=-1){ if(ch=='\r') continue; if(ch=='\n') return sb.toString(); sb.append((char)ch); } if(sb.length()!=0) return sb.toString(); return null; } public void myClose() throws IOException{ fr.close(); } } public class Main { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("ACM.txt"); MyBufferedReader msb = new MyBufferedReader(fr); String str = null; while((str = msb.MyReadLine())!=null){ System.out.println(str); } msb.myClose(); } }
二、装饰设计模式
当对一组对象的功能进行增强时,就可以使用该模式进行问题的解决,上述的自定义MyBufferedReader类就是很好的体现,对于FileReader类比原来的功能简便,当然上述代码写的比较简单
class Room{ public void show(){ System.out.println("房子"); } } class NewRoom { private Room or; public NewRoom(OldRoom or) { // TODO Auto-generated constructor stub this.or = or; } public void show(){ or.show(); System.out.println("平房"); } }
一定要避免的是修改源代码,当然继承也可以实现功能的增强。
但是继承的话,会让继承体系复杂且麻烦
装饰设计模式和继承的区别:
继承:如果为了增强功能,就要继续写子类,只是为了一个新的NewRoom,就要创建一个子类,NewRoom后出现别墅呢,又要创建子类,逐渐的,导致继承体系越来越臃肿
装饰设计模式:无论NewRoom还是别墅,都是Room的一种,都保持着房子的基本属性
所以,利用装饰设计模式,只需要把被装饰的对象传入即可,可以将缓冲技术单独抽取进行封装,要缓冲区谁将谁和缓冲相关联即可,这样的设计的相对体系会变的简单。
三、LineNumberReader
API文档解释:跟踪行号的缓冲字符输入流。此类定义了方法setLineNumber(int)
和getLineNumber()
,它们可分别用于设置和获取当前行号。
import java.io.*; public class Main { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("ACM.txt"); LineNumberReader lr = new LineNumberReader(fr); String str = null; lr.setLineNumber(10);//设置行号从10开始 while((str = lr.readLine())!=null){ System.out.println(str+" line : "+lr.getLineNumber()); } lr.close(); } }
此类用的地方不是很多,知道怎么用即可。
四、练习
一定要用字节流文件复制媒体文件
import java.io.*; public class Main { public static void main(String[] args) throws IOException { //copy_mp3_1(); //copy_mp3_2();//开发建议使用这种 copy_mp3_3(); } public static void copy_mp3_3() throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("D:\\盛夏光年.mp3"); FileOutputStream fos = new FileOutputStream("D:\\盛夏光年3.mp3"); byte[] by = new byte[fis.available()];//局限:文件过大,就不行了 fis.read(by); fos.write(by); fos.close(); fis.close(); } public static void copy_mp3_2() throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("D:\\盛夏光年.mp3"); BufferedInputStream br = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("D:\\盛夏光年2.mp3"); BufferedOutputStream bw = new BufferedOutputStream(fos); int len = 0; while((len = br.read())!=-1){ bw.write(len); bw.flush(); } br.close(); bw.close(); } public static void copy_mp3_1() throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("D:\\盛夏光年.mp3"); FileOutputStream fos = new FileOutputStream("D:\\盛夏光年1.mp3"); byte[] by = new byte[1024];//注意Mp3文件的字节数,这个数组越接近效率越块 int len = 0; while((len = fis.read(by))!=-1){ fos.write(len); fos.flush(); } fos.close(); fis.close(); } }
JAVA学习第四十九课 — IO流(三):缓冲区2 & 装饰设计模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。