栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK源码==》InputStream、OutputStream、BufferedInputStream 和 BufferedOutputStream类学习

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK源码==》InputStream、OutputStream、BufferedInputStream 和 BufferedOutputStream类学习

文章目录

1、InputStream和OutputStream2、BufferedInputStream 和 BufferedOutputStream

BufferedInputStream 类的继承与实现关系及对应的成员变量、构造、方法BufferedIOutputStream 类的继承与实现关系及对应的成员变量、构造、方法demo:red读取内容:write写内容:

1、InputStream和OutputStream

public abstract class InputStream implements Closeable {

    // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
    // use when skipping.
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;
    
}    

有上面内容可知,InputStream是一个抽象类实现了Closeable接口,,也间接实现了AutoCloseable接口,有一个成员变量MAX_SKIP_BUFFER_SIZE,用于确定跳过时使用的最大缓冲区大小

public abstract class OutputStream implements Closeable, Flushable {
    
}

由上面可知,OutputStream也是一个抽象类,实现了Closeable, Flushable接口,也间接实现了AutoCloseable接口

2、BufferedInputStream 和 BufferedOutputStream BufferedInputStream 类的继承与实现关系及对应的成员变量、构造、方法

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[];
    
    private static final
        AtomicReferenceFieldUpdater bufUpdater =
        AtomicReferenceFieldUpdater.newUpdater
        (BufferedInputStream.class,  byte[].class, "buf");
    
    protected int count;
    
    protected int pos;
    
    protected int markpos = -1;
    
    protected int marklimit;
    
    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];
    }
    
}    
BufferedIOutputStream 类的继承与实现关系及对应的成员变量、构造、方法

public class BufferedOutputStream extends FilterOutputStream {
	// 缓冲区大小
    protected byte 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];
    }    
}    
demo:

从一个文件中内容,写入到另外一个文件

public static void main(String[] args) throws IOException {
        try(
                // 获取缓冲输入流
                BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E://hello.txt"));
                // 获取缓冲输出流
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("hello.txt"));
           )
        {
            // 获取读取的内容数据的长度
            int available = bufferedInputStream.available();
            System.out.println("available = " + available);
            // 存储读取的字节内容
            byte[] aa = new byte[available];
            int i = 0;
            while ((i = bufferedInputStream.read(aa)) != -1){
                // 写入读取的字节内容
                bufferedOutputStream.write(aa);
            }
        }
    }

获取读取的内容数据的长度:
int available = bufferedInputStream.available();

	 public synchronized int available() throws IOException {
        int n = count - pos;
        int avail = getInIfOpen().available();
        return n > (Integer.MAX_VALUE - avail)
                    ? Integer.MAX_VALUE
                    : n + avail;
    }
	// 判断输入流是否关闭
	private InputStream getInIfOpen() throws IOException {
        InputStream input = in;
        if (input == null)
            throw new IOException("Stream closed");
        return input;
    }
	
	// FileInputStream类中的available()
    public int available() throws IOException {
        return available0();
    }
	// FileInputStream类中的available0(),且该方法使用了native修饰
    private native int available0() throws IOException;
red读取内容:
    // FilterInputStream类里面的read(byte b[]),FilterInputStream类的子类重写了该方法
	public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }
	//BufferedInputStream类里面的read(byte b[], int off, int len)
	public synchronized int read(byte b[], int off, int len)
        throws IOException
    {
        getBufIfOpen(); // Check for closed stream
        if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int n = 0;
        for (;;) {
            // 获取读取的内容的长度
            int nread = read1(b, off + n, len - n);
            if (nread <= 0)
                return (n == 0) ? nread : n;
            n += nread;
            if (n >= len)
                return n;
            // if not closed but no bytes available, return
            InputStream input = in;
            if (input != null && input.available() <= 0)
                return n;
        }
    }
	//BufferedInputStream类里面的read1(byte b[], int off, int len)
    private int read1(byte[] b, int off, int len) throws IOException {
        int avail = count - pos;
        if (avail <= 0) {
			// 判断一次读取的长度是否大于缓冲区的容量大小及确定markpos是否小于0
            if (len >= getBufIfOpen().length && markpos < 0) {
                return getInIfOpen().read(b, off, len);
            }
            // 第一次读取前获取读取的内容的总长度
            fill();
            avail = count - pos;
            if (avail <= 0) return -1;
        }
        int cnt = (avail < len) ? avail : len;
        System.arraycopy(getBufIfOpen(), pos, b, off, cnt);
        // 移动开始读取的索引
        pos += cnt;
        return cnt;
    }

	private void fill() throws IOException {
        // 获取缓冲区
        byte[] buffer = getBufIfOpen();
        if (markpos < 0)
            pos = 0;            
        else if (pos >= buffer.length)  
            if (markpos > 0) {  
                int sz = pos - markpos;
                System.arraycopy(buffer, markpos, buffer, 0, sz);
                pos = sz;
                markpos = 0;
            } else if (buffer.length >= marklimit) {
                markpos = -1;   
                pos = 0;        
            } else if (buffer.length >= MAX_BUFFER_SIZE) {
                throw new OutOfMemoryError("Required array size too large");
            } else {            
                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;
    }
write写内容:
	// FilterOutputStream类里面的write(byte b[]),FilterOutputStream类的子类重写了该方法
	public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }
	// BufferedOutputStream类里面的write(byte b[], int off, int len)
	public synchronized void write(byte b[], int off, int len) throws IOException {
        // 判断是否大于缓冲区的长度
        if (len >= buf.length) {
            
            // 刷新缓冲区
            flushBuffer();
            // 写入数据
            out.write(b, off, len);
            return;
        }
        // 判断缓冲区剩余的长度是否大于要写入的内容的长度
        if (len > buf.length - count) {
            flushBuffer();
        }
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }
    // 刷新缓冲区
    private void flushBuffer() throws IOException {
        if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }
	// 写入数据
	public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
    }
    public synchronized void write(int b) throws IOException {
        if (count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte)b;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/760791.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号