黑马程序员_IO_上

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

IO(Input Output)流用来处理设备之间的数据传输。
Java用于操作流的对象都在IO包中。
1.流按操作数据分为两种:字节流与字符流 。
2.流按流向分为:输入流,输出流。

字节流的抽象基类:
InputStream ,OutputStream
字符流的抽象基类:
Reader ,Writer
由这四个类派生出来的子类名称都是 以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。

分离出字符流的原因:字符流的对象里面融合了编码表。
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类。
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类。
字符流和字节流归根到底还是通过字节流操作文件,字符流先向将数据放入缓存,在从缓存中把数据放入文件。

专门用于操作文件的Writer子类对象:FileWriter

fw.close()与fw.flush()的区别就是fw.flush()刷新后流可以继续使用,而fw.close()是关闭流之前调用fw.flush()进行刷新。

FileReader:


运用read()方法一次读取一个字符直到读取到-1认为读到文件末尾。为了提高流的操作效率出现了BufferedReader、BufferedWriter。
缓冲区的出现是为了提高流的操作效率而出现的。所以在创建缓冲区之前,必须要先有流对象。
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。这就是“换行”和“回车”的来历。

    后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
Unix系统里,每行结尾只有“<换行>”,即“\n”;
Windows系统里面,每行结尾是“<换行><回车>”,即“\n\r”;
Mac系统里,每行结尾是“<回车>”。
则该缓冲区中提供了一个跨平台的换行符。newLine();

BufferedWriter:


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

装饰类设计模式:

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

继承的方式:

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

以前是通过继承将每一个子类都具备缓冲功能。
那么继承体系会复杂,并不利于扩展。
现在优化思想:单独描述一下缓冲内容。
将需要被缓冲的对象。传递进来,谁需要被缓冲,谁就作为参数传递给缓冲区。
这样继承体系就变得很简单,优化了体系结构。

装饰设计模式与继承的比较

1.装饰把继承变成了组合

2.装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。

装饰设计模式举例:


人本来只有吃饭这个功能,当我想对它进行增强时,就定义一个装饰类SuperPerson类,并将Person对象作为参数传进去,增加功能,当我想用增强功能时就调用SuperPerson中的superChifan方法,想调用原来的chifan()方法时,也可以直接用p.chifan();进行调用,这样既增加了代码的扩展性,而且减少了继承带来的代码的臃肿。

字节流:

FileInputStream,FileOutputStream



字节流的读一个字节的read方法返回值类型不是byte,而是int,因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。所以,为了避免这种情况将读到的字节进行int类型的提升。并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。11111111  -->提升了一个int类型 ,还是-1,是-1的原因是因为在8个1前面补的是1导致的。
那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。所以在写入数据时,只写该int类型数据的最低8位。

转换流

readLine()方法是字符流BufferedReader类中的方法。
而键盘录入的read()方法是字节流InputStream的方法。
将字节流转成字符流在使用字符流缓冲去的readLine方法()就使用到了转换流。
InputStreamReader、OutputStreamWriter
根据后缀名是父类名,前缀名是该流对象的功能的原则我们也可了解到这两个流对象是作为转换使用的。
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。 

字符流和字节流结构图


----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值