字符流的缓冲区

  • 缓冲区的出现提高了对数据的读写效率。
  • 对应类:
    •   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. SKTransition类

    继承自 NSObject 符合 NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0 ...

  2. [Angular 2] Using ngrx/store and Reducers for Angular 2 Application State

    ngrx/store is a library that simplifies common RxJS patterns for managing state and gives you an eas ...

  3. [RxJS] Combining streams in RxJS

    Source: Link We will looking some opreators for combining stream in RxJS: merge combineLatest withLa ...

  4. shell 脚本实现的守护进程

    转自:http://blog.csdn.net/cybertan/article/details/3235722 转自:http://blog.sina.com.cn/s/blog_4c451e0e0 ...

  5. 《C专家编程》之一

    一.解决函数返回指针的几种方法 1. 返回一个指向字符串常量的指针. 例子: char* func() { rturn "Only work for simple strings" ...

  6. Hadoop安装测试简单记录

    安装的节点如下:1个namenode.1个hiveserver.3个dataNode192.168.1.139   namenode1192.168.1.146   hiveserver 192.16 ...

  7. 黑信 socket即时通讯 示例

    整个过程 首先开启服务器 打开一个SDK大于4.4的手机---B 打开一个SDK小于4.4的手机---A 相互发送一条消息,对方就可以收到,当然这些消息都是通过服务器[转发]过来的 MainActiv ...

  8. codevs 1173 最优贸易(DP+SPFA运用)

    /* 中国的题目 ——贱买贵卖 0.0 这题wa了好多遍 第一遍看着题 哎呀这不很简单嘛 从起点能到的点都是合法的点 然后统计合法的点里最大最小值 然后printf 也不知道哪里来的自信 就这么交了 ...

  9. ASP.NET-FineUI开发实践-3

    1.参照模拟数据库分页通过缓存重写内存分页,优化页面响应速度 Grid的响应速度是硬伤,我写了个通用方法把所有数据放在缓存中模拟数据库分页,比自带的缓存分页快很多,这里贴上实体类的通用方法,DataT ...

  10. jQuery自定义组件——输入框设置默认提示文字

    if (window.jQuery || window.Zepto) { /** * 设置输入框提示信息 * @param options * @author rubekid */ var setIn ...