字符流的缓冲区

  • 缓冲区的出现提高了对数据的读写效率。
  • 对应类:
    •   BufferedWriter
    • BufferedReader
  • 缓冲区要结合流才可以使用。
  • 在流的基础上对流的功能进行了增强。

BufferedWriter

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

缓冲区的出现是为了提高流的操作效率而出现的。所以在创建缓冲区之前,必须要先有流对象。

void newLine():写入一个行分隔符。(跨平台换行符)

import java.io.*;

class BufferedWriterDemo
{
pubilc static void main(String[] args)Throws IOException
{
//创建一个字符写入流对象。
FileWriter fw = new FileWriter("buf.txt"); //为了提高字符流写入效率,加入了缓冲技术。原理:对象里面封装了数组。只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw = new BufferedWriter(fw); buyw.write("abcde"); //记住,只要用到缓冲区,就要记得刷新。
bufw.flush(); //其实关闭缓冲区,就是在关闭缓冲区的流对象。
bufw.close(); } }

BufferedReader

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

String readLine():读取一个文本行。(该缓冲区提供了一个一次读一行的方法,方便与对文本数据的获取。当返回null时,表示读到文件末尾。

import java.io.*;

class BufferReaderDemo
{
pubic static void main(String[] args)
{
//创建一个读取流对象与文件相关联。
FileReader fr = new FileReader("buf.txt"); //为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数。
BufferedReader bufr = new BufferedReader(fr); String line = null; while((line=bufr.readLIne()) !null)
{
System.out.pritnln(line);
} bufr.close(); } }

通过缓冲区复制文本文件

练习:通过缓冲区复制一个.java文件。

readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。

readLine方法原理:无论是读一行,获取读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终使用的还是read方法,一次读一个的方法。

import java.io.*;

class CopyTestByBuf
{
public static void main(String[] args)
{
BufferReader bufr = null;
BufferWriter bufw = null;
try
{
bufr = new BufferReader(new FileReader("BufferedWriterDemo.java"));
bufw = new BufferedWriter(new FileWriter("bufWriter_copy.txt")); String line = null; while((line = bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.fiush(); }
ctach(IOException e)
{
throw new RuntimeException("读写失败");
} finally
{
try
{
if(bufr!=null)
bufr.close();
}
catch(IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(bufw!=null)
bufw.close();
}
catch(IOException e)
{
throw new RuntimeException("写入关闭失败");
}
} }
} }

myBufferedReader

明白了BufferedReader类中特有方法readLine的原理后,可以自定义一个类中包含一个功能和readLine一致的方法。来模拟一下BufferedReader。

import java.io.*;

class MyBufferedReader
{
private FileReader r;
MyBufferedReader(r)
{
this.r = r;
} //可以一次读一行数据的方法。
public String myReadLine()throws IOException
{
//定义一个临时容器,原BufferedReader封装的是字符数组。
//为了演示方便,定义一个StringBuilder容器,因为还要将数据变成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
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();
return null;
}
pubilc void myClose()throws IOException
{
r.close();
}
} class MyBufferedReaderDemo
{
public static void main(String[] args)throws IOException
{
FileReader fr = new FileReader("buf.txt"); MyBufferedReader myBuf = new MyBufferedReader(fr); String line = null; while((line = myReadLine())!=null)
{
System.out.println(line);
}
muBuf.mtClose(); } }

装饰设计模式

由上述例子可见,readLine()方法是在增强read()方法,通过将被增强的对象传给增强类,提供了一个基于它的读一行的方法,MyBufferedReader其实就是在对FlieReader进行增强,那么这种方式我们也把它称之为一种设计模式,叫做装饰设计模式。 

装饰设计模式:当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,基于已有功能,并提供加强功能,那么自定义的该类称为装饰类。 

装饰类通常会通过构造方法接收被装饰对象并基于被装饰的对象的功能,提供更强的功能。

class Person
{
public void chifan()
{
Systam.out.println("吃饭");
}
} class SuperPerson
{
private Person p;
SuperPerson(Person P)
{
this.p = p;
}
public void superChifan()
{
Systam.out.println("开胃酒");
p.chifan();
Systam.out.println("甜点");
Systam.out.println("来一根"); }
} class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person();
SuperPerson sp = new SuperPerson(p); sp.superChifan();
} }

装饰和继承的区别

MyReader//专门用于读取数据的类。

  |--MyTextReader

    |--MyBufferTextReader

  |--MyMediaReader

    |--MyBufferMediaReader

  |--MyDateReader

    |--MyBufferDateReader

继承体系虽然能用,但是扩展性非常不好,体系臃肿。需要进行优化,发行着三个类扩展出来的都是同一种技术,所以单独定义一个缓冲类MyBufferReader。

class MyBufferReader

{

MyBufferReader(MyTextReader text)

{}

MyBufferReader(MyMediaReader media)

{}

}

上面这个类扩展性很差,找到其参数的共同类型,通过多态的形式,可以提高扩展性。

class MyBufferReader extends MyReader

{

private MyReader r ;

MyBufferReader(MyReader r)

{

this.r = r;

}

}

优化后体系:

MyReader

  |--MyTextReader

  |--MyMediaReader

  |--MyDateReader

  |--MyBufferReader

装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰类通常都是属于同一个体系中。(所属同一个父类或者同一个接口)

自定义装饰类

import java.io.*;

class MyBufferedReader extends Reader
{
private Reader r;
MyBufferedReader(Reader r)
{
this.r = r;
} //可以一次读一行数据的方法。
public String myReadLine()throws IOException
{
//定义一个临时容器,原BufferedReader封装的是字符数组。
//为了演示方便,定义一个StringBuilder容器,因为还要将数据变成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
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();
return null;
}
//覆盖Reader类中的抽象方法。
public int read(char[] cbuf,int off,int len)throws IOException
{
r.read(cbuf,off,len);
} public void close()throws IOException
{
r.close();
} pubilc void myClose()throws IOException
{
r.close();
}
} class MyBufferedReaderDemo
{
public static void main(String[] args)throws IOException
{
FileReader fr = new FileReader("buf.txt"); MyBufferedReader myBuf = new MyBufferedReader(fr); String line = null; while((line = myReadLine())!=null)
{
System.out.println(line);
}
muBuf.mtClose(); } }

LineNumberReader装饰类

LineNumberReader:跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int)getLineNumber(),它们可分别用于设置和获取当前行号。

import java.io.*;

class LineNumberReaderDemo
{
publiv static void main(String[] args)throws IOException
{
FileReader fr = new FileReader("PersonDemo.java");
LineNumberReader lnr = new LineNumberReader(fr); String line = null;
lnr.setLineNumber(100); while((line= lnr.readline())!=null)
{
System.out.println(lnr.getLineNumber+":"+line);
} lnr.close();
} }

练习:模拟一个带行号的缓冲区对象。

MyLIneNumberReader

import java.io.*;

class MyLineNumberReader extends myBufferedReader
{
private int lineNumber;
MyLineNumberReader(Reader r)
{
super(r);
} public String myReadline()
{
lineNumber++;
super myReadLine();
} public int setLineNumber(int lineNumber)
{
this.lineNumber = lineNumber;
} public int getLineNumber()
{
return lineNumber;
}
} /* class MyLineNumberReader
{
private Reader r;
private int lineNumber;
MyLineNumberReader(Reader r)
{
this.r = r;
} public String myReadline()
{
lineNumber++;
StringBuilder sb = new StringBuilder();
int ch = 0;
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();
return null;
} public int setLineNumber(int lineNumber)
{
this.lineNumber = lineNumber;
} public int getLineNumber()
{
return lineNumber;
}
public void myClose()
{
r.close();
}
}
*/ class MyLineNumberReaderDemo
{
public static void main(String[] args)throws IOException
{
FileReader fr = new FileReader("copyTextByBuf.java)
MyLIneNumberReader mylnr = new MyLIneNumberReader(fr); Stirng line = null; mylnr.setLineNumber(100); while((line = mylnr.myReadLine())!null)
{
System.out.println(mylnr.getLineNumber+"::"+line);
}
mylnr.myClose();
}
}

。。。。。。

黑马程序员_JavaIO流(二)的更多相关文章

  1. 黑马程序员_JavaIO流(四)

    File概述 File类 用来将文件或者文件夹封装成对象. 方便对文件与文件夹的属性信息进行操作. File对象可以作为参数传递给流的构造函数. 了解File类中的常用方法. 字段:static St ...

  2. 黑马程序员_JavaIO流(一)

    IO(Input Output)流 概述: IO流(数据流)用来处理设备之间的数据传输. Java对数据的操作是通过流的方式. Java用于操作流的对象都在IO包中. 流按操作数据分为两种:字节流与字 ...

  3. 黑马程序员_JavaIO流(三)

    字节流File读写操作 字符流: FileReader FileWriter BufferedReader BufferedWrtier 字节流: FileInputStream FileOutput ...

  4. 黑马程序员-IO(二)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 装饰设计模式: 当想要对已有对象进行功能增强时.可以定义类,将已经有的类传入,基于已经有的功能, ...

  5. 黑马程序员-集合(二)contains()方法的内部探索

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 我们知道集合是用来存储对象的.在他们实现了众多的接口我们以Arraylist为列子 所有已实现的 ...

  6. 黑马程序员——【Java高新技术】——代理

    ---------- android培训.java培训.期待与您交流! ---------- 一.“代理概述”及“AOP概念” (一)代理概述 1.问题:要为已存在的多个具有相同接口的目标类的各个方法 ...

  7. 黑马程序员:轻松精通Java学习路线连载1-基础篇!

    编程语言Java,已经21岁了.从1995年诞生以来,就一直活跃于企业中,名企应用天猫,百度,知乎......都是Java语言编写,就连现在使用广泛的XMind也是Java编写的.Java应用的广泛已 ...

  8. 黑马程序员:3分钟带你读懂C/C++学习路线

    随着互联网及互联网+深入蓬勃的发展,经过40余年的时间洗礼,C/C++俨然已成为一门贵族语言,出色的性能使之成为高级语言中的性能王者.而在今天,它又扮演着什么样重要的角色呢?请往下看: 后端服务器,移 ...

  9. 【黑马18期Java毕业生】黑马程序员Java全套资料+视频+工具

        Java学习路线图引言:        黑马程序员:深知广大爱好Java的人学习是多么困难,没视频没资源,上网花钱还老被骗. 为此我们历时一个月整理这套Java学习路线图,不管你是不懂电脑的小 ...

随机推荐

  1. 查询表达式Linq

    LINQ简介 OO(面向对象)以外的疆域:信息的访问与整合.关系数据库与XML为其中的典型应用. .net Language Integrated Query(Linq):不采用特定关于数据库与XML ...

  2. 导出可执行的jar

    1.在你要导出的项目上单击右键,在弹出的右键菜单里选择:Export…选项. 2.在弹出的对话框里选择:,然后点击下边的Next; 3.在弹出的对话框里,点击选择导出后的jar存储路径以及文件名.(其 ...

  3. STL之Pairs

    什么是Pair 关于类Pair的介绍,下面是引自<C++ Standard Library>的一段话: The class pair is provided to treat two va ...

  4. RHEL7查看网卡配置命令ip addr show

    Validating Network Address Configuration To verify the configuration of the network address, you nee ...

  5. HTML5中class选择器属性的解释

    设置有class属性值的元素,可以被css中的选择器调用,也可以在javascript中以getElementsByClassName()方法调用. 可以给各个元素添加class而且名称可以相同与id ...

  6. 在C#中internal关键字是什么意思?和protected internal区别

    我来补充一下,对于一些大型的项目,通常由很多个DLL文件组成,引用了这些DLL,就能访问DLL里面的类和类里面的方法.比如,你写了一个记录日志的DLL,任何项目只要引用此DLL就能实现记录日志的功能, ...

  7. 什么是DNN,Dotnetnuke介绍和功能简介

    1. What is DNN? DNN是DotNetNuke(DotNet)的简写.它是在IBUYSPY(IBUYSPY是微软用来推广ASP.NET而推出的范例程序)的基础上发展起来的,是一个免费的. ...

  8. DNN模块开发之利器篇:七种武器

    我们在进行DNN模块开发时经常需要调用Dotnetnuke.dll中的方法函数,模块开发用到DNN的方法函数会让你的开发更加得心应手,下面我们就来介绍一下.   1) PortalModuleBase ...

  9. 历史执行Sql语句性能分析 CPU资源占用时间分析

    SELECT     HIGHEST_CPU_QUERIES.PLAN_HANDLE,     HIGHEST_CPU_QUERIES.TOTAL_WORKER_TIME,     Q.DBID,   ...

  10. 初级班 Linux使用

    ifconfig 查看IP地址 重新启动网卡服务 service network restart 笔记 1.通过远程工具登陆到linux后,所在的位置是当前登录用户的家目录(home director ...