美文网首页java.io源码解析
java.io源码解析(七)--缓冲流(BufferedInpu

java.io源码解析(七)--缓冲流(BufferedInpu

作者: dark丶Night | 来源:发表于2019-05-31 15:07 被阅读0次

    声明:本系列只供本人自学使用,勿喷。

    缓冲流本质上是通过一个内部缓冲区数组实现的。例如,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

    那么为什么需要内部缓冲呢?答案是效率。因为普通的InputStream读取数据是需要逐个字节读取,假如原始数据是在硬盘上,那速度会很慢。而运用BufferedInputStream,则可以一次性读n个字节到内存中的缓冲区,这样在内存中读取数据会快很多。

    一、BufferedInputStream

    • 构造器(入参必须有InputStream )
    public class BufferedInputStream extends FilterInputStream{
        private static int DEFAULT_BUFFER_SIZE = 8192;
        private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
        // 缓冲数组
        protected volatile byte buf[];
        // bufUpdater提供buf的compareAndSet方法,这是必要的,因为close()可以是异步的,可以将buf是否为null作为是否close的主要指标。
        private static final AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
            AtomicReferenceFieldUpdater.newUpdater(BufferedInputStream.class,  byte[].class, "buf");
        // buf中的有效字节数
        protected int count;
        // buf中的当前字节位置
        protected int pos;
        
        public BufferedInputStream(InputStream in) {
            this(in, DEFAULT_BUFFER_SIZE);
        }
    
        public BufferedInputStream(InputStream in, int size) {
            super(in);
            if (size <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            }
            buf = new byte[size];
        }
    }
    
    • 核心方法
        // 往buf填充数据,方法里主要是考虑到mark的几种情况
        private void fill() throws IOException
    
        public synchronized int read() throws IOException {
            // 当读完buf中的数据后,就需要把InputStream的数据重新填充到buf
            if (pos >= count) {
                fill();
                if (pos >= count)
                    return -1;
            }
            // 返回buf的下一个字节
            return getBufIfOpen()[pos++] & 0xff;
        }
    
        private int read1(byte[] b, int off, int len) throws IOException
    
        // 调用 read1
        public synchronized int read(byte b[], int off, int len) throws IOException
    
    • 其他方法
    public synchronized long skip(long n) throws IOException
    public synchronized int available() throws IOException
    public synchronized void mark(int readlimit)
    public synchronized void reset() throws IOException
    public boolean markSupported()
    

    二、BufferedOutputStream

    • 构造器(入参必须有OutputStream )
    public class BufferedOutputStream extends FilterOutputStream{
        private static int DEFAULT_BUFFER_SIZE = 8192;
        private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
        // 缓冲数组
        protected byte buf[];
        // buf中的有效字节数
        protected int count;
    
        public BufferedOutputStream(OutputStream out) {
            this(out, 8192);
        }
    
        public BufferedOutputStream(OutputStream out, int size) {
            super(out);
            if (size <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            }
            buf = new byte[size];
        }
    }
    
    • 核心方法
        public synchronized void write(int b) throws IOException
    
        public synchronized void write(byte b[], int off, int len) throws IOException
        
        public synchronized void flush() throws IOException
    

    三、BufferedReader

    • 构造器(入参必须有Reader)
    public class BufferedInputStream extends FilterInputStream{
        private Reader in;
        private static int defaultCharBufferSize = 8192;
        private static int defaultExpectedLineLength = 80;
        // 缓冲数组
        private char cb[];
        // 其他 mark相关变量
    
        public BufferedReader(Reader in) {
            this(in, defaultCharBufferSize);
        }
    
        public BufferedReader(Reader in, int sz) {
            super(in);
            if (sz <= 0)
                throw new IllegalArgumentException("Buffer size <= 0");
            this.in = in;
            cb = new char[sz];
            nextChar = nChars = 0;
        }
    }
    
    • 核心方法
    public int read() throws IOException
    public int read(char cbuf[], int off, int len) throws IOException
    public String readLine() throws IOException
    
    • 其他方法
    public long skip(long n) throws IOException
    public boolean ready() throws IOException
    public boolean markSupported()
    public void mark(int readAheadLimit) throws IOException
    public void reset() throws IOException
    public void close() throws IOException
    public Stream<String> lines()
    

    四、BufferedWriter

    • 构造器(入参必须有Writer)
    public class BufferedWriter extends Writer{
        private Writer out;
    
        private char cb[];
        private int nChars, nextChar;
    
        private static int defaultCharBufferSize = 8192;
    
        private String lineSeparator;
    
        public BufferedWriter(Writer out) {
            this(out, defaultCharBufferSize);
        }
    
        public BufferedWriter(Writer out, int sz) {
            super(out);
            if (sz <= 0)
                throw new IllegalArgumentException("Buffer size <= 0");
            this.out = out;
            cb = new char[sz];
            nChars = sz;
            nextChar = 0;
    
            lineSeparator = java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction("line.separator"));
        }
    }
    
    • 核心方法
    public void write(int c) throws IOException
    public void write(char cbuf[], int off, int len) throws IOException
    public void write(String s, int off, int len) throws IOException
    public void newLine() throws IOException
    
    • 其他方法
    public void flush() throws IOException
    public void close() throws IOException
    

    相关文章

      网友评论

        本文标题:java.io源码解析(七)--缓冲流(BufferedInpu

        本文链接:https://www.haomeiwen.com/subject/xwkwtctx.html