java IO流总结篇(一)

来源:互联网 发布:中国项目数据分析师 编辑:程序博客网 时间:2024/05/22 22:01
/***@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 2
原创粉丝点击