Java文件操作(三)——浅谈Java中I/O(下)

本文深入探讨了Java中的I/O流,包括节点流与处理流的概念,详细介绍了工厂模式和装饰者模式在I/O操作中的应用,并进行了总结。
摘要由CSDN通过智能技术生成

什么是节点流和处理流

    在[Java文件操作(二)——浅谈Java中I/O(上)](http://blog.csdn.net/qq_24789865/article/details/48835713)中,我把Java中的IO分类为两大类,第一种是字节流,第二种是字符流。这是根据它们在处理数据时的方式不同来分类的(字节流处理数据以字节为基础,字符流以字符为基础),在这里我们换一个角度,以功能不同来对Java中的IO进行分类。

    根据功能的不同,我们又可以把Java中的IO分为:
    1.节点流
    2.处理流

    所谓节点流呢,你可以想象它是一根真实的管道,它里面流淌着真实的数据(具体实现了对数据的读或写),而处理流呢,就是在节点流这根管道上新增了一些功能,它可以对节点流中的数据进行进一步的处理。可能这种说法比较抽象,下面我们就通过代码来看一下Java中的处理流是怎样的

    在这之前,先说一下今天用到的一个处理流BufferedReader

    当你看到它的第一眼,你应该就知道,它首先是一个字符输入流(以“Reader”结尾),然后它是一个处理流,所以它又叫做“字符输入处理流”,他有一个核心方法:
    public String readLine();
    即一次读取一行数据,返回值为null时,代表数据读取结束

    示例代码:
import java.io.*;

public class Test{
    public static void main(String args[]){

        FileReader fr = null;

        BufferedReader bfr = null;

        try{
            //创建一个字符节点流对象
            fr = new FileReader("F:/from.txt");
            //创建一个处理流对象,并传入一个节点流
            bfr = new BufferedReader(fr);

            String line = null;

            while(true){
                line = bfr.readLine();
                if(line == null){
                    break;
                }
                System.out.println(line);
            }

        }
        catch(Exception e){
            System.out.println(e);
        }

    }

}
    BufferedReader在创建对象的时候,是将FileReader的对象作为参数传递给了BufferedReader的对象。在进行数据处理的时候,真正实现数据读取的功能是FileReader的对象,而BufferedReader是对FileReader所读取的数据在readLine()中进行进一步处理,进而实现了一次读取一行的功能。其实这整个过程就是一个典型的“工厂模式”的实现(也叫做“装饰者模式”)

工厂模式(装饰者模式)

    下面我们就通过另外一个例子来,来帮助大家进一步理解“工厂模式”的思想:

    上图中,【员工】是对所有不同工种的员工的一个抽象,具体实现【员工】的可以是一个水管工,可以是一个木匠,可以是一个电工等,这样,就有很多个不同的工种。但是不能是什么工种的员工,他们终将属于某一家公司,无论是A公司,B公司,C公司......,那么问题来了,如果有m个工种,n家公司,并且每家公司都有m个工种,按照传统的继承体系就要写m*n个员工类(A公司水管,B公司水管工,C公司水管工......),这显然是相当繁冗的,那么我们可不可以通过一个什么方法,我们不用把所有的公司的所有员工的类都一一写出来,而是当公司需要一个什么样员工的时候,就生成一个什么样的员工,这样一来,事情就变得非常简洁了。嗯,没错,这就是“工厂模式”的核心思想:需要的时候再创建。

    下面我们通过代码来具体实现上面的案例:
    (1)首先,创建一个Worker接口,它代表了所有员工的抽象:
interface Worker{


    public void doSomeWork();


}
    (2)分别创建Plumbe类和Carpenter类,他们具体是实现【水管工】  和【木匠】,它们都是Worker的子类:

    Plumbe类:
public class Plumber implements Worker{

    public void doSomeWork(){
        System.out.println("修水管");
    }

}
水管工要做的事就是“修水管”,所以重写方法中打印“修水管”。

Carpenter类:
public class Carpenter implements Worker{
    public void doSomeWork(){
        System.out.println("修门窗");
    }
}
木匠要做的事就是“修门窗”,所以重写方法中打印“修门窗”

    (3)创建AWorker类和BWorker类,它们分别代表了A公司员工的抽象和B公司所有员工的抽象,它们都是Worker的子类:

    AWorker类:
public class AWorker implements Worker{


    private Worker worker;

    public AWorker(Worker worker){
        this.worker = worker;
    }

    public void doSomeWork(){
        System.out.println("你好!");
        worker.doSomeWork();

    }

}
    BWorker类:
public class BWork() implements Worker{

    private Worker worker;

    public BWorker(Worker worker){
        this.worker = worker;
    }

    public void doSomeWork(){
        System.out.println("穿鞋套!");
        worker.doSomeWork();
    }

}
    细心的读者可能注意到了,在这两个类中,都有声明一个Worker的引用。那么,它在这里有什么用呢?

    哈哈哈哈,其实这就是今天我要说的“工厂模式”的思想的精髓所在。。。。

    【A公司员工】类(Aworker)的内部的有一个【员工引用】(private Worker worker),实际上这个引用就代表了一个员工,这个员工可能是【水管工】(Plumbe),可能是【木匠】(Carpenter)等,在A公司没有这个工种的时候,它是不确定的。当A公司需要一个工种(比如【水管工】)的时候,就直接把【水管工】这个类的对象作为参数赋值给这个【员工引用】,此时此刻,【员工引用】就代表了一个水管工,这个【A公司员工】就变成了一个【A公司水管工】,同理,如果传递的是【木匠】这个类的对象,这个【A公司员工】就变成了一个【A公司木匠】......

    (3)写一个测试类:
class Test{
    public static void main(String args[]){

        //被装饰者:
        Plumber p = new Plumber();
        //装饰者:
        AWorker a = new AWorker(p);

        a.doSomeWork();
    }
    运行结果:
你好!
修水管
    在这个过程中【A公司员工】是一个“装饰者”,【水管工】是一个“被装饰者”,【水管工】最初能做的事只有“修水管”,但是在通过【A公司员工】进行装饰过后,他就会在“修水管”之前先说“你好”。

总结

    在了解的工厂模式的思想后,再回到代码中,我们就知道了FileReader相当于“【水管工】”,是一个“被装饰者”,它真正实现了对数据的读取,而BufferedReader相当于“【A公司员工】”,是一个“装饰者”,它用来“装饰”FileReader,在FileReader所拥有的功能的基础上,新增了一次读取一行的功能。此外,BufferedReader作为一个“装饰者”,它不仅仅可以装饰FileReader,只要是Reader的子类它都可以装饰。

    所以,在Java中节点流和处理流之间,节点流就是“被装饰者”,处理流就是“装饰着”,节点流在被处理流“装饰”后,就可以在节点流原有功能的基础上,实现一些新的功能。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值