IO装饰器模式学习

面向对象的写法学习

  • 类似HessianOutput对OutputStream 的面向对象封装写法,普通写法就是os.write啥的,而面向对象写法是利用HessianOutput对os进行操作的.
  • 先看一下将文件信息缓存的普通写法, 再看下面向对象的写法,其实BufferedInputStream就是这么做的,FileInputStream是装饰器父类,负责批量从文件读取信息,而BufferedInputStream则把信息放到缓存区。
  • 代码第一段是从一个个读单字节读取文件 到批量读取 再到面向对象的批量读取方式。
/**
 * 从一个个读单字节读取文件 到批量读取 再到面向对象的批量读取方式
 */
public class TestBufferedInput {

    private static String FILE_PATH = "D:/test.txt";

    public static void main(String[] args) throws IOException {
        /**
         * 面向对象的批量读取方式
         */
        InputStream is = new MyBufferedInputStream(new FileInputStream(new File(FILE_PATH)));
        is.read();
    }

    /**
     * 单字节读取文件
     * 假设读取一个字节需要的时间为0.1毫秒,那么一个1M字节大小的文件,则需要1024 * 1024 = 104857.6毫秒,也即104秒.。
     * 同时假设处理一个字节需要0.01,处理完毕需要10秒。
     */
    public static void readFileOneByOne() {
        try {
            final File file = new File(FILE_PATH);
            final FileInputStream is = new FileInputStream(file);
            int data = -1;
            //逐个字节读取处理
            while((data = is.read()) != -1) {
                //处理它
                System.out.println((char) data);
            }
        } catch(IOException ioex) {
            ioex.printStackTrace();
        }
    }

    /**
     * 批量读取
     */
    public static void readFileOneByMore() {
        try {
            final File file = new File(FILE_PATH);
            final FileInputStream is = new FileInputStream(file);
            int data = -1;
            //缓存容器
            byte[] datas = new byte[1024];
            //批量字节读取处理
            while((data = is.read(datas)) != -1) {
                //处理它
                System.out.println(new String(datas, 0, 1024));
            }
        } catch(IOException ioex) {
            ioex.printStackTrace();
        }
    }

    /**
     * BufferedInputStream的使用方法
     */
    public static void buffered() {
        try {
            /**
             * 建立输入流 BufferedInputStream, 缓冲区大小为8
             * buffer.txt内容为
             * avsfdswrer
             */
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File("D:/test.txt")));
        /*从字节流中读取5个字节*/
            byte [] tmp = new byte[5];
            in.read(tmp, 0, 5);
            System.out.println("字节流的前5个字节为: " + new String(tmp));
        /*标记测试*/
            in.mark(6);
        /*读取5个字节*/
            in.read(tmp, 0, 5);
            System.out.println("字节流中第6到10个字节为: " +  new String(tmp));
        /*reset*/
            in.reset();
            System.out.printf("reset后读取的第一个字节为: %c \n" , in.read());
            System.out.printf("reset后读取的第2个字节为: %c" , in.read());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

public class MyBufferedInputStream extends FilterInputStream {
    //面向对象思想管理
    private byte[] buf;

    private static final int DEFAULTSIZE = 8092;

    /**
     * 下一个读取字节的位置.
     */
    private int pos;

    /**
     * 当前缓冲数组中有效字节个数.
     */
    private int count;

    public MyBufferedInputStream(final InputStream in) {
        this(in, DEFAULTSIZE);
    }

    public MyBufferedInputStream(final InputStream in, final int size) {
        super(in);
        this.buf = new byte[size];
    }

    /**
     * 读取缓冲数组中的字节.
     */
    public int read() throws IOException {
        //当buf中已经缓存的字节都读取完了,那么将输入流的数据继续读入缓存buf中.
        if(pos >= count) {
            fill();
            //当发现输入流已经读取完毕了,那么退出.
            if(pos >= count) {
                return -1;
            }
        }
        return this.buf[pos++] & 0xff;  
    }

    /**
     * 将输入流in填充缓冲数组buf.
     */
    private void fill() throws IOException {
        this.count = this.in.read(this.buf, 0, this.buf.length);
        this.pos = 0;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容