黑马程序员_JavaIO流(二)
字符流的缓冲区
- 缓冲区的出现提高了对数据的读写效率。
- 对应类:
- 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流(二)的更多相关文章
- 黑马程序员_JavaIO流(四)
File概述 File类 用来将文件或者文件夹封装成对象. 方便对文件与文件夹的属性信息进行操作. File对象可以作为参数传递给流的构造函数. 了解File类中的常用方法. 字段:static St ...
- 黑马程序员_JavaIO流(一)
IO(Input Output)流 概述: IO流(数据流)用来处理设备之间的数据传输. Java对数据的操作是通过流的方式. Java用于操作流的对象都在IO包中. 流按操作数据分为两种:字节流与字 ...
- 黑马程序员_JavaIO流(三)
字节流File读写操作 字符流: FileReader FileWriter BufferedReader BufferedWrtier 字节流: FileInputStream FileOutput ...
- 黑马程序员-IO(二)
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 装饰设计模式: 当想要对已有对象进行功能增强时.可以定义类,将已经有的类传入,基于已经有的功能, ...
- 黑马程序员-集合(二)contains()方法的内部探索
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 我们知道集合是用来存储对象的.在他们实现了众多的接口我们以Arraylist为列子 所有已实现的 ...
- 黑马程序员——【Java高新技术】——代理
---------- android培训.java培训.期待与您交流! ---------- 一.“代理概述”及“AOP概念” (一)代理概述 1.问题:要为已存在的多个具有相同接口的目标类的各个方法 ...
- 黑马程序员:轻松精通Java学习路线连载1-基础篇!
编程语言Java,已经21岁了.从1995年诞生以来,就一直活跃于企业中,名企应用天猫,百度,知乎......都是Java语言编写,就连现在使用广泛的XMind也是Java编写的.Java应用的广泛已 ...
- 黑马程序员:3分钟带你读懂C/C++学习路线
随着互联网及互联网+深入蓬勃的发展,经过40余年的时间洗礼,C/C++俨然已成为一门贵族语言,出色的性能使之成为高级语言中的性能王者.而在今天,它又扮演着什么样重要的角色呢?请往下看: 后端服务器,移 ...
- 【黑马18期Java毕业生】黑马程序员Java全套资料+视频+工具
Java学习路线图引言: 黑马程序员:深知广大爱好Java的人学习是多么困难,没视频没资源,上网花钱还老被骗. 为此我们历时一个月整理这套Java学习路线图,不管你是不懂电脑的小 ...
随机推荐
- android中画文字的换行 办法(对于遇到canvas.drawText(String s )无法实现换行问题的解决)
在使用canvas.drawText()绘制文字的时候,发现,如果需要绘制的文字较长,需要换行,通过在文字中加上“\n"或者”\r\n"都无法实现换行,如果非要使用canvas.d ...
- url参数中有+、空格、=、%、&、#等特殊符号的处理
url参数中有+.空格.=.%.&.#等特殊符号的问题解决? 解决办法: 将这些字符转化成服务器可以识别的字符,对应关系如下: URL字符转义 + URL 中+号表示空格 %2B 空格 URL ...
- Creating LVM Logical Volumes
LVM-Logical Volume Manager逻辑卷管理的一些基本概念: 用途: 在零停机前提下可以自如对文件系统的大小进行调整,可以方便实现文件系统跨越不同磁盘和分区.当系统添加了新的磁盘,通 ...
- 从零基础入门JavaScript(1)
从零基础入门JavaScript(1) 1.1 Javascript的简史 1995年的时候 由网景公司开发的,当时的名字叫livescript 为了推广自己的livescript,搭了j ...
- 字符串转化为json的三种方法
1,eval方式解析,恐怕这是最早的解析方式了.如下: function strToJson(str){ var json = eval('(' + str + ')'); return json; ...
- ADB错误“more than one device and emulator”(转)
当我连着手机充电的时候,启动模拟器调试,执行ADB指令时,报错.C:\Users\gaojs>adb shellerror: more than one device and emulatorC ...
- ImageView的学习
学习安卓时我还是习惯看懂手册,虽然是英文但是可以获得的东西必然也是更多的,否则自己只能停留在拾人牙缝的水平,虽然我是初学,但是还是分享一些自己的学习过程及方法. 从手册中我们看以知道,ImageVie ...
- 关于iOS应用管理之九宫格的坐标计算以及与UIScrollView的结合
关于九宫格的布局以及坐标的计算,对于大多数的iOS初学者甚至有一定能力的学者来说都是一大难题,在此写者通过自己的开发经验以及多次应用,把自己的所学所得分享给大家,就通过应用管理来进行浅谈一二. ...
- JavaScript 之 使用 XMLHttpRequest 上传文件
<div id="div1"> <input type="file" id="uploadfile" style=&quo ...
- 27 Java动态加载第三方jar包中的类
我加载的方法是://参数fileName是jar包的路径,processorName 是业务类的包名+类名public static A load(String fileName, String pr ...