JavaIO从其出生的时候就存在了,其主要包含
面向字节的输入输出流:InputStream,OutputStream
面向字符的输入输出流:Reader,Writer
(这四个都是抽象类,不能直接实例化)
字节是计算机的存储单位,8位;而字符只是在内存中才存在的,16位;
由于Java本身Char就是16位的Unicode,所以一开始也有人说Reader,Writer就是给String用的
在有时候我们需要把“字节”层次的类和“字符”层次的类结合起来使用,这就需要用到“适配器(adaoter)”类:
InputSteamReader:可以吧InputSteam转换成Reader
OutputStreamWriter:可以吧OutputStream转换成Writer
字符流和字节流还有很大的区别就是缓冲区的(内存)概念:
字节流会直接操作文件;
字符流会现将文件放入缓冲区,缓冲区满了或者关闭时才进行传输
这一点可以自己实验,使用两种方式向文件里写数据,都不关闭流,查看文件时只有字节流的文件里有数据,而字符流由于未关闭流,而缓冲区又没满,所以其不会写数据。
这可能有点像nio,不过我们目前研究的是bio,虽然在jdk1.4之后bio底层也用nio重写了,不过留给我们的操作接口是这样的。
从设计模式看
io包采用的装饰着模式,这也是为什么最主要的四个类InputStream,OutputStream,Reader,Writer是抽象类的原因
装饰着模式:在菜鸟教程上有详细的解释,这里我就只说明我的观点:
其有一个基类(InputStream),其规定了需要实现的基本方法;
有一个对其基本实现的类(FilterInputStream),这个类一般不会直接实例化‘
有一个暴露给用户的使用类(BufferedInputStream),一般都是实例化这个类,这个类也叫装饰类
有一个直接继承基类的被装饰类(FileInputStream),其也叫被装饰类,他不用管被怎么装饰,他只用实例化就行了
不过对比之后发现原装饰者模式中基类是个接口,基本实现的类是个抽象类,暴露给用户的实用类和被装饰类是实体类。不过思想是这个思想,具体实现有所差别也是没办法的事情
不过从IO的通常使用上我们可以看出来其是装饰者模式的,如下
BufferedInputStream bufferedInputStream =
new BufferedInputStream(new FileInputStream("a.txt"));
这和菜鸟驿站上的例子不是一样的吗
Shape redRectangle = new RedShapeDecorator(new Rectangle());