BufferedInputStream/BufferedOutputStream

Posted 小淘气儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BufferedInputStream/BufferedOutputStream相关的知识,希望对你有一定的参考价值。

BufferedInputStream:

public synchronized int read() throws IOException

int res=bis.read();

System.out.println((char)res)

  调用一次,取一次值,并游标向前走一位;返回值为unicode

 public synchronized int read(byte b[], int off, int len) throws IOException
 
 byte[] buff=new byte[LEN];
 
 int res=bis.read(buff,0,LEN);
 
 System.out.println(new String(buff,0,res));

    调用一次 取LEN个值,并游标向前走LEN位,数据保存在字节数组中,返回值是数据个数

 

public synchronized int available() throws IOException 

  返回目标文件大小, 底层实现?

 public synchronized void mark(int readlimit)  
 public synchronized void reset() throws IOException

  mark用来标记断点(下标)并传入一个readlimit (缓冲流最大限制)

      reset 将返回到断点重新读取数据

 

根据源码解读:


  public synchronized void mark(int readlimit) {
        marklimit = readlimit;
        markpos = pos;
    }


    public synchronized void reset() throws IOException {
        getBufIfOpen(); // Cause exception if closed
        if (markpos < 0)
            throw new IOException("Resetting to invalid mark");
        pos = markpos;
    }   

  

 private void fill() throws IOException {
        byte[] buffer = getBufIfOpen();
        if (markpos < 0)
            pos = 0;            /* no mark: throw away the buffer */
        else if (pos >= buffer.length)  /* no room left in buffer */
            if (markpos > 0) {  /* can throw away early part of the buffer */
                int sz = pos - markpos;
                System.arraycopy(buffer, markpos, buffer, 0, sz);
                pos = sz;
                markpos = 0;
            } else if (buffer.length >= marklimit) {
                markpos = -1;   /* buffer got too big, invalidate mark */
                pos = 0;        /* drop buffer contents */
            } else if (buffer.length >= MAX_BUFFER_SIZE) {
                throw new OutOfMemoryError("Required array size too large");
            } else {            /* grow buffer */
                int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
                        pos * 2 : MAX_BUFFER_SIZE;
                if (nsz > marklimit)
                    nsz = marklimit;
                byte nbuf[] = new byte[nsz];
                System.arraycopy(buffer, 0, nbuf, 0, pos);
                if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
                    // Can‘t replace buf if there was an async close.
                    // Note: This would need to be changed if fill()
                    // is ever made accessible to multiple threads.
                    // But for now, the only way CAS can fail is via close.
                    // assert buf == null;
                    throw new IOException("Stream closed");
                }
                buffer = nbuf;
            }
        count = pos;
        int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
        if (n > 0)
            count = n + pos;
    }

  

 1、调用mark 并传入int类型参数赋值给marklimit,同时将pos赋值给markpos;

   2、在读取数据过程中,在没调用reset前,pos会持续自增;

   3、 在缓冲区中数据读取完后,会再次调用fill方法,使缓冲区扩大一倍,然后pos继续自增

   接下来有三种运行路线

   1、缓冲区大小超过marklimit时,调用reset时,会抛异常,因为markpos=-1;

   2、缓冲区大小超过最大缓冲区大小,直接抛异常

   3、缓冲区大小没有超过marklimit,调用reset,缓冲区大小回到初始值大小,将markpos复制给pos,返回到标记点,重新读取数据;

 

还有查看源码发现,如果缓冲区大小没有超过marklimit,,那么这个标记一直存在,知道缓冲close;没有找到去掉标记的方法;

 

BufferedOutputStream:

 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

 private void flushBuffer() throws IOException 

  

 

以上是关于BufferedInputStream/BufferedOutputStream的主要内容,如果未能解决你的问题,请参考以下文章