java-io-源码-字节流

字节流

一. OutputStream

规定了write、flush、close方法由子类实现;
write写数组的方法,检查一下输入参数,然后针对byte数组的每个值,调用write方法

public abstract class OutputStream implements Closeable, Flushable {
    public abstract void write(int b) throws IOException;

    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    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 void flush() throws IOException {}
    public void close() throws IOException {}
}

二. InputStream

public abstract class InputStream implements Closeable {
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    public abstract int read() throws IOException;

    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }
	//skip就是读取一次,越过一些数量
    public long skip(long n) throws IOException {
        long remaining = n;
        int nr;

        if (n <= 0) {
            return 0;
        }

        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
        byte[] skipBuffer = new byte[size];
        while (remaining > 0) {
            nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
            if (nr < 0) {
                break;
            }
            remaining -= nr;
        }

        return n - remaining;
    }
	//可以读到数据的估计
    public int available() throws IOException {
        return 0;
    }

    public void close() throws IOException {}
	//标记一次读取,的当前位置
    public synchronized void mark(int readlimit) {}
	//回到上一次的Mark位置
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    public boolean markSupported() {
        return false;
    }
}

三. FileOutputStream

成员如下:

private final FileDescriptor fd;
private final boolean append;
private FileChannel channel;
private final String path;
private final Object closeLock = new Object();
private volatile boolean closed = false;

构造函数
构造函数创建,把文件名转化为File

  	public FileOutputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null, false);
    }

获取fd、append、path,并打开文件

   public FileOutputStream(File file, boolean append)
        throws FileNotFoundException {
        String name = (file != null ? file.getPath() : null);
        ...
        this.fd = new FileDescriptor();
        fd.attach(this);
        this.append = append;
        this.path = name;
        open(name, append);
    }

write
针对这个文件描述符,调用本地方法writeBytes

    public void write(byte b[]) throws IOException {
        writeBytes(b, 0, b.length, append);
    }

总结:FileOutputStream就是c中的file读写

四. BufferedOutputStream

BufferedOutputStream的父类为FilterOutputStream
FilterOutputStream的内部维持了一个OutputStream,其调用的方法都是内部OutputStream的方法,filter的操作都是在它的子类中

BufferedOutputStream
代码中BufferedOutputStream可以修饰所有的OutputStream
构造函数如下;

    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

内部构建了一个8192的数组,把out传进来

    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

写方法

    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

调用的wite方法,为BufferedOutputStream复写的
如果传入数组的长度比buf还长,那么直接调用输出流的写方法;
如果剩余的buf空间不够,则刷出;要不将内容拷贝的buf中

    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();
        }
		//c的memcpy方法
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

flushBuffer就是把内部buf的内容直接刷出,这个只是内部的BufferedOutputStream的flush操作,如果out本身有缓冲,那么没有被刷出

    private void flushBuffer() throws IOException {
        if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }

flush是彻底的刷出

   public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }

五. DataOutputStream

BufferedOutputStream的继承关系如下,最终BufferedOutputStream也是一个输出流,可以用其他的内容继续修饰
BufferedOutputStream->FilterOutputStream->OutputStream
DataOutputStrea

   public DataOutputStream(OutputStream out) {
        super(out);
    }

DataOutputStream把各种类型的数据封装成byte,通过调用内嵌的out的方法,将不同数据类型的内容写出去;
分别按照int,String,long三种类型将数据写出,还提供了writeUTF方法

posted @ 2016-09-26 21:32  zhangshihai1232  阅读(165)  评论(0)    收藏  举报