Java面向对象——IO流(字符流缓冲区)

欢迎光临新长城博客中心


面向对象

字符流的缓冲区

1、缓冲区的出现提高了对数据的读写效率。

2、对应类。

(1)、BufferedWriter

(2)、BufferedReader

3、缓冲区要结合流才可以使用。

4、在流的基础上对流的功能进行了增强。

BufferWriter

 void newLine()
          写入一个行分隔符。

/*

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

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

*/

import java.io.IOException;

import java.io.Writer;

import java.io.FileWriter;

import java.io.BufferedWriter;

public class Test{

public static void main(String...args) throws IOException{

Writer w = new FileWriter("C:\\1.Java");

/*

为了提高字符写入流的效率,加入了缓冲技术,只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可

*/

BufferedWriter bw = new BufferedWriter(w);

bw.write("程序员");

/*

当然如果要刷新的话,当然是要刷新缓存区的flush,

因为数据写到缓冲区里面去了。

如果刷新流对象是刷不出来东西的。关闭也一样

*/

bw.newLine();

bw.write("我来了");

bw.flush();

//bw.close();

/*其实这个流可以不用关闭也行。因为缓存区必须有流,而流对象关闭了。

缓存区对象也就自动释放了*/

w.close();

}

}

IO流(BufferedReader)

BufferedReader

 String readLine()
          读取一个文本行。

readLine() 读取一个文本行。返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾, 则返回 null ,所有要手动写入换行.

 /*
字符读取流缓冲区:
该缓冲区提供了一个一次读一行的方法 readLine ,方便于对文本数据的获取
当返回 null 时,表示读到文件的末尾
readLine() 方法返回的时候只返回回车符之前的数据内容,并不返回回车符
*/

import java.io.Reader;

import java.io.FileReader;

import java.io.IOException;

import java.io.BufferedReader;

public class Test{

public static void main(String...args) throws IOException{

Reader r = new FileReader("C:\\1.Java");

/*

为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数

*/

BufferedReader br =  new BufferedReader(r);

for(String line = null;(line=br.readLine())!=null;){

System.out.print(line);

System.out.println();

}

}

}

IO流(通过缓冲区复制文本文件)
/*
通过缓冲区复制一个 .Java 文件

*/

import java.io.IOException;

import java.io.BufferedWriter;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.FileWriter;

public class Test{

public static void main(String...args){

BufferedReader br = null;

BufferedWriter bw = null;

try{

br =new BufferedReader(new FileReader("C:\\1.Java"));

 bw = new BufferedWriter(new FileWriter("C:\\2.Java"));

for(String line = null;(line=br.readLine())!=null;){

bw.write(line);

bw.newLine();

bw.flush();

}

}

catch(IOException e){

throw new RuntimeException("读写失败");

}

finally{

try{

if(br!=null)

br.close();

}

catch(IOException e){

throw new RuntimeException("读取关闭失败");

}

try{

if(bw!=null)

bw.close();

}

catch(IOException e){

throw new RuntimeException("写入关闭失败");

}

}

}

}

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

因为跨平台性,换行符不一样,所以读取的时候缓存中不存入换行,让使用者自己输入换行。

IO流(MyBufferedReader)

明白了BufferedReader 类中特有方法 readLine 的原理后,

可以自定义一个类中包含一个功能和readLine一致的方法

来模拟一下BufferedReader的readLine方法。

import java.io.IOException;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;

public class Test{

public static void main(String... args) throws IOException{

Reader r = new FileReader("C:\\1.Java");

MyBufferedReader br = new MyBufferedReader(r);

for(String line =null;(line=br.myReadLine())!=null;){

System.out.print(line);

System.out.println();

}

}

}

class MyBufferedReader{

private Reader r;

MyBufferedReader(Reader r){

this.r=r;

}

public String myReadLine() throws IOException{

/*

定义一个临时容器,原BufferedReader封装的是字符数组

为了方便,定义一个StringBuilder容器,因为最终还是要将数据变成字符串

*/

StringBuilder sb = new StringBuilder ();

int len = 0;

while((len = r.read())!=-1){

if(len=='\r')

continue;

if(len=='\n')

return sb.toString();

else

sb.append((char)len);

}

//防止最后一行没有换行的情况

if(sb.length()!=0)

return sb.toString();

else

return null;

}

public void myClose() throws IOException{

r.close();

}

}

IO流(装饰设计模式)

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

(可以理解为打扮,比如自己如果要去面试的化,咱们要把自己打扮一下,把自己搞上点新鲜的衣服,但是最后还是一个人,只是身上多个点东西,这就是装饰)

IO流(装饰和继承的区别)

以前是通过继承将每一个子类都具备父类的功能。

那么继承体系会复杂,并不利于扩展。

现在优化思想。单独描述一下装饰类的内容。

将需要被装饰的对象。传递进来。也就是,谁需要被装饰,谁就作为参数传递给装饰类。

这样继承体系就变得很简单。优化了体系结构。


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

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


IO流(自定义装饰类)

abstract class Person{

public abstract  void  chifan(); 

}

class Qiongren extends Person{

public void chifan(){

System.out.println("吃饭");

}

}

class Furen extends Person{

private Person p;

Furen(Person p){

this.p=p;

}

public void chifan(){

System.out.println("开胃酒");

p.chifan();

System.out.println("甜点");

System.out.println("来一根,当然我不好这口");

}

}

public class Test{

public static void main(String...args){

Qiongren q =new Qiongren();

Furen f =new Furen(q);

f.chifan();

}

}

IO流(LineNumberReader)

LineNumberReader

 int getLineNumber()
          获得当前行号。

 void setLineNumber(int lineNumber)
          设置当前行号。

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.LineNumberReader;

import java.io.IOException;

public class Test{

public static void main(String... args) throws IOException{

BufferedReader br = new BufferedReader(new FileReader("C:\\1.Java"));

LineNumberReader lnr = new  LineNumberReader(br);

lnr.setLineNumber(100);

for(String line =null;(line=lnr.readLine())!=null;){

System.out.println(lnr.getLineNumber()+":"+line);

}

lnr.close();

}

}

IO流(MyLineNumberReader)

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class MyLineNumberReader{

private BufferedReaderbr;

private int LineNumber;

MyLineNumberReader(BufferedReader br){

this.br=br;

}

public void setLineNumber(int LineNumber){

this.LineNumber =  LineNumber;

}

public int getLineNumber(){

return++LineNumber;

}

public String readLine()throwsIOException{

return br.readLine();

}

public void myClose() throws IOException{

br.close();

}

}

public class Test{

public static void main(String...args) throws IOException{

BufferedReader bfr = new BufferedReader(new FileReader("C:\\1.Java"));

MyLineNumberReader my = new MyLineNumberReader(bfr);

my.setLineNumber(100);

for(String line = null;(line=my.readLine())!=null;){

System.out.println(my.getLineNumber()+":"+line);

}

my.myClose();

}

}

相信大家看我的博客的时候看的很累,让我们为了我们共同的梦想努力吧。我相信只要我们坚持就会成功的。


你可能感兴趣的:(黑马程序员,io流,面向对象,字符流,缓存)