黑马程序员—Java基础—IO2

来源:互联网 发布:掏粪男孩 知乎 编辑:程序博客网 时间:2024/06/04 18:08


                                ------- android培训、java培训、期待与您交流! ----------

                                               

 IO2 

一、BufferedWriter

缓冲区的出现是为了提高流的操作效率而出现的。

所以在创建缓冲区之前,必须要先有流对象。

该缓冲区中提供了一个跨平台的换行符。

newLine();

import java.io.*;class  BufferedWriterDemo{public static void main(String[] args) throws IOException{//创建一个字符写入流对象。FileWriter fw = new FileWriter("buf.txt");//为了提高字符写入流效率。加入了缓冲技术。//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。BufferedWriter bufw = new BufferedWriter(fw);for(int x=1; x<5; x++){bufw.write("abcd"+x);bufw.newLine();//写一次,刷一次,可以防止断电时数据的丢失bufw.flush();}//记住,只要用到缓冲区,就要记得刷新。//bufw.flush();//其实关闭缓冲区,就是在关闭缓冲区中的流对象。bufw.close();}}

二、readLine


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

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

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

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

三、通过缓冲区复制文本文件

//通过缓冲区复制一个.java文件。import java.io.*;class  CopyTextByBuf{public static void main(String[] args) {BufferedReader bufr = null;BufferedWriter bufw = null;try{bufr = new BufferedReader(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.flush();}}catch (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("写入关闭失败");}}}}


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

<span style="font-size:18px;">import java.io.*;class MyBufferedReader {private Reader r;MyBufferedReader(Reader r){this.r = r;}//可以一次读一行数据的方法。public String myReadLine()throws IOException{//定义一个临时容器。原BufferReader封装的是字符数组。//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1){if(ch=='\r')continue;  //返回执行while判断语句if(ch=='\n')return sb.toString(); //返回缓冲区存放的字符串数据elsesb.append((char)ch);//往定义的StringBuilder容器中添加字符}if(sb.length()!=0)   //最后没有回车,返回已经读取的数据return sb.toString();return null;}public 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=myBuf.myReadLine())!=null){System.out.println(line);}myBuf.myClose();}}</span>


四、装饰设计模式
装饰设计模式:
当想要对已有的对象进行功能增强时,
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象。
并基于被装饰的对象的功能,提供更强的功能。

<span style="font-size:18px;">class Person{public void chifan(){System.out.println("吃饭");}}class SuperPerson {private Person p ;SuperPerson(Person p){this.p = p;}public void superChifan(){System.out.println("开胃酒");p.chifan();System.out.println("甜点");System.out.println("来一根");}}class  PersonDemo{public static void main(String[] args) {Person p = new Person();//p.chifan();SuperPerson sp = new SuperPerson(p);sp.superChifan();}}</span>

五、装饰和继承的区别

//super.方法() 表示在子类中调用父类方法
//可以自己写个类,将已有的类对象传入,提高灵活性
MyReader//专门用于读取数据的类。
|--MyTextReader
|--MyBufferTextReader
|--MyMediaReader
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader


class MyBufferReader
{
MyBufferReader(MyTextReader text)
{}
MyBufferReader(MyMediaReader media)
{}
}
上面这个类扩展性很差。
找到其参数的共同类型。通过多态的形式。可以提高扩展性。

class MyBufferReader extends MyReader
{
private MyReader r;
MyBufferReader(MyReader r)
{}
}

MyReader//专门用于读取数据的类。
|--MyTextReader
|--MyMediaReader
|--MyDataReader
|--MyBufferReader


以前是通过继承将每一个子类都具备缓冲功能。
那么继承体系会复杂,并不利于扩展。

现在优化思想。单独描述一下缓冲内容。
将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。
这样继承体系就变得很简单。优化了体系结构。

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

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。

所以装饰类和被装饰类通常是都属于一个体系中的。


六、自定义装饰类

import java.io.*;class MyBufferedReader extends Reader{private Reader r;MyBufferedReader(Reader r){this.r = r;}//可以一次读一行数据的方法。public String myReadLine()throws IOException{//定义一个临时容器。原BufferReader封装的是字符数组。//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1){if(ch=='\r')continue;  //返回执行while判断语句if(ch=='\n')return sb.toString(); //返回缓冲区存放的字符串数据elsesb.append((char)ch);}if(sb.length()!=0)   //最后没有回车,返回已经读取的数据return sb.toString();return null;}//覆盖Reader类中的抽象方法。public int read(char[] cbuf, int off, int len) throws IOException{return r.read(cbuf,off,len) ;}public void close()throws IOException{r.close();}public 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=myBuf.myReadLine())!=null){System.out.println(line);}myBuf.myClose();}}

七、LineNumberReader

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

默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,并且可以通过调用 setLineNumber(int) 更改行号。
但要注意的是,setLineNumber(int) 不会实际更改流中的当前位置;它只更改将由 getLineNumber() 返回的值。 

可认为行在遇到以下符号之一时结束:换行符('\n')、回车符('\r')、回车后紧跟换行符。 


import java.io.*;class LineNumberReaderDemo {public 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

//LineNumberReader方法原理//原始代码import java.io.*;class MyLineNumberReader {private Reader r;private int lineNumber;MyLineNumberReader(Reader r){this.r=r;}public String myReadLine()throws IOException{lineNumber++;StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1){if(ch=='\r')continue;if(ch=='\n')return sb.toString();elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;}public void myClose()throws IOException{r.close();}}class  MyLineNumberReaderDemo{public static void main(String[] args) throws IOException{FileReader fr = new FileReader("CopyText.java");MyLineNumberReader mylnr = new MyLineNumberReader(fr);String line = null;mylnr.setLineNumber(100);while((line=mylnr.myReadLine())!=null){System.out.println(mylnr.getLineNumber()+"::"+line);}mylnr.myClose();}}//优化后的代码import java.io.*;class MyLineNumberReader extends MyBufferedReader{private int lineNumber;MyLineNumberReader(Reader r){super(r);}public String myReadLine()throws IOException{lineNumber++;return super.myReadLine();}public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;}}class  MyLineNumberReaderDemo{public static void main(String[] args) throws IOException{FileReader fr = new FileReader("CopyText.java");MyLineNumberReader mylnr = new MyLineNumberReader(fr);String line = null;mylnr.setLineNumber(100);while((line=mylnr.myReadLine())!=null){System.out.println(mylnr.getLineNumber()+"::"+line);}mylnr.myClose();}}







0 0
原创粉丝点击