java IO流总结篇(一)

/**
*@author StormMaybin
*Date 2016-07-28
*/

生命不息,奋斗不止!


IO流是一个很重要的概念,不经常用难免会忘记,所以我们共同来复习一下这个庞大而且重要的东西,IO流总结会分为两篇,按照字节流和字符流展开!


流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流的分类
  • 根据处理数据类型的不同分为:字符流和字节流
  • 根据数据流向不同分为:输入流和输出流
字符流和字节流
  • 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
  • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
输入流和输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

IO流的基本概念就介绍到这,下来先来看看java中IO流的框架体系

这里写图片描述

初识IO框架,会有一种茫然失措的感觉,那么现在我们先从字符流最简单的操作——读写,开始看!

字符流
  • Reader

    • Reader 是所有的输入字符流的父类,它是一个抽象类。
    • CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。
    • BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。
    • FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。
    • InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。
  • Writer

    • Writer 是所有的输出字符流的父类,它是一个抽象类。
    • CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,
    • BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
    • PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
    • OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。

我们先来看看怎么创建一个文件,然后往里面写入数据

package com.stormma.writer;
import java.io.*;
public class FileWriterDemo
{
    public static void main(String[] args)
    {
        FileWriter fileWriter = null;
        //关联流和文件的时候,会抛出找不到文件异常,这个异常是IOException的子类,所以我们在这里try,catch一下
        try
        {
            fileWriter = new FileWriter("writer.txt");
            fileWriter.write("abcde");
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
        finally
        {
            if (fileWriter != null)
            {
                try
                {
                    //关闭流之前会自动刷新
                    fileWriter.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

这里写图片描述

既然已经成功写入数据了,接下来开始读取文件的数据

package com.stormma.reader;
import java.io.*;
public class FileReaderDemo
{

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        FileReader fileReader = null;
        try
        {
            fileReader = new FileReader("writer.txt");
            /***
             * 单个字符读取
             *  int ch = 0;
             *  while ((ch = fileReader.read()) != -1)
             *  {
             *      System.out.print((char)ch);
             *  }
             */
            char [] buf = new char [5];
            int num = 0;
            num = fileReader.read(buf);
            System.out.println(buf);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (fileReader != null)
            {
                try
                {
                    fileReader.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }

    }

}

这里写图片描述


很明显上面的代码效率太低,那么对应的缓冲区的出现很好的提高了流的操作效率!查阅源代码可以发现,BufferedReader装饰了Reader,从而提高了流的操作效率,从而演变出来的是java中的装饰设计模式,这种模式很好的降低了类与类的耦合性!

这里写图片描述

演示代码
package com.stormma.FileReaderWriter;
import java.io.*;

public class BufferedReaderDemo
{

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        FileReader fr = null;
        BufferedReader bufr = null;
        String lines = null;
        try
        {
            fr = new FileReader("buf.txt");
            bufr = new BufferedReader(fr);
            while ((lines = bufr.readLine()) != null)
            {
                System.out.println(lines);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(fr != null)
            {
                try
                {
                    fr.close();
                }
                catch(IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

这里写图片描述
读取和写入是一样的,写入数据对应的类BufferedWriter可以直接写入一行!

我们仔细观察上面的代码,不难发现经过BufferedReader的装饰之后,读取数据可以一次读取一行,这样很好的提高了流的操作效率,但是readLine()方法是怎么实现的呢?我们可不可以自己定义一个BufferReader类来实现这些功能呢?答案是肯定的!

自定义BufferedReader
package com.stormma.FileReaderWriter;
import java.io.*;
/***
 * 自定义BufferedReader
 * 实现readLine()方法
 * @author StormMaybin
 *
 */
public class MyBufferedReader
{
    private FileReader fr;
    /***
     * BufferedReader初始化参数是流对象
     * 所以这里的构造函数应该是带有流对象的构造函数
     * @author StormMaybin
     * @param fr
     */
    public MyBufferedReader(FileReader fr)
    {
        this.fr = fr;
    }
    public String myReadLine()throws IOException
    {
        /***
         * BufferedReader的readLine()方法
         * 内部是调用的FileRader中的read 方法
         * 并且用数组来存储读取的字符,这里为了方便,
         * 定义一个StringBuilder容器来存储读到的
         * 字符
         * 
         */
        StringBuilder sb = new StringBuilder();
        int ch = 0;
        //因为这里的read方法有可能会抛出异常
        //所以这个函数申明可抛出异常
        while ((ch = fr.read()) != -1)
        {
            if (ch == '\r')
            {
                continue;
            }
            else if (ch == '\n')
            {
                return sb.toString();
            }
            else
            {
                sb.append((char)ch  );
            }
        }
        //避免丢失最后一行
        if (sb.length() != 0)
        {
            return sb.toString();
        }
        return null;
    }
    /***
     * myClose方法
     * 实现关闭流功能
     * @throws IOException
     */
    public void myClose()throws IOException
    {
        fr.close();
    }
}

我们新建一个类使用自定义的readLine()方法

/***
 * 演示类
 * @author StormMaybin
 *
 */
class MyBufferedReaderDemo 
{
    //这里为了方便,没有trycatch,直接抛出去了!
    public static void main (String [] args)throws IOException
    {
        FileReader fr = new FileReader("buf.txt");
        MyBufferedReader mbufr = new MyBufferedReader(fr);
        String lines = null;
        while ((lines = mbufr.myReadLine()) != null)
        {
            System.out.println(lines);
        }
        mbufr.myClose();
    }
}

演示结果和上面的结果是一致的
这里写图片描述

  • 9
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值