国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java 字節流源碼解析

geekidentity / 1336人閱讀

摘要:重要方法一個一個字節讀取,放到數組中重要方法讀取一個字節調用方法讀取的內容調用方法聲明繼承自構造方法從中讀取一個字節歸根究底,目的是將數據放入中緩存,下次讀取可以直接獲取重要方法調用模板方法,由子類實現寫一

1. InputStream

重要方法:

    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;
    }

一個一個字節讀取,放到byte數組中

1.1 FileInputStream

重要方法:

// 讀取一個字節  
public int read() throws IOException {
    return read0();
}

// 調用 native 方法
private native int read0() throws IOException;
// 讀取b.length的內容
public int read(byte b[]) throws IOException {
    return readBytes(b, 0, b.length);
}

public int read(byte b[], int off, int len) throws IOException {
    return readBytes(b, off, len);
}

// 調用 native 方法
private native int readBytes(byte b[], int off, int len) throws IOException;
1.2 BufferedInputStream 1.2.1 聲明
// 繼承自 FilterInputStream
public class BufferedInputStream extends FilterInputStream 
1.2.2 構造方法
private static int DEFAULT_BUFFER_SIZE = 8192;

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];
}

// super(in);
protected FilterInputStream(InputStream in) {
    this.in = in;
}
1.2.3 read
public synchronized int read() throws IOException {
    if (pos >= count) {
        fill();
        if (pos >= count)
            return -1;
    }
    // 從buf中讀取一個字節
    return getBufIfOpen()[pos++] & 0xff;
}

private byte[] getBufIfOpen() throws IOException {
    byte[] buffer = buf;
    if (buffer == null)
        throw new IOException("Stream closed");
    return buffer;
}
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;
    }
}

private int read1(byte[] b, int off, int len) throws IOException {
    int avail = count - pos;
    if (avail <= 0) {
        /* If the requested length is at least as large as the buffer, and
               if there is no mark/reset activity, do not bother to copy the
               bytes into the local buffer.  In this way buffered streams will
               cascade harmlessly. */
        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;
}

// 歸根究底,目的是將數據放入buffer中緩存,下次讀取可以直接獲取
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;
}
private int read1(byte[] b, int off, int len) throws IOException {
    int avail = count - pos;
    if (avail <= 0) {
        /* If the requested length is at least as large as the buffer, and
               if there is no mark/reset activity, do not bother to copy the
               bytes into the local buffer.  In this way buffered streams will
               cascade harmlessly. */
        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;
}
2. OutputStream

重要方法:

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]);
    }
}
2.1 FileOutputStream 2.1.1 write
// 寫一個字節
public void write(int b) throws IOException {
    write(b, append);
}

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

private native void writeBytes(byte b[], int off, int len, boolean append)
    throws IOException;
public void write(byte b[], int off, int len) throws IOException {
    writeBytes(b, off, len, append);
}
2.2 BuffedOutputStream 2.2.1 聲明
public class BufferedOutputStream extends FilterOutputStream 
2.2.2 constructor
// 在內存中申請一個 byte[]
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];
}
2.2.3 write
// 寫一個字節
public synchronized void write(int b) throws IOException {
    if (count >= buf.length) {
        flushBuffer();
    }
    buf[count++] = (byte)b;
}

// 調用 outputstream 的 write方法
private void flushBuffer() throws IOException {
    if (count > 0) {
        out.write(buf, 0, count);
        count = 0;
    }
}
public synchronized void write(byte b[], int off, int len) throws IOException {
    if (len >= buf.length) {
        /* If the request length exceeds the size of the output buffer,
               flush the output buffer and then write the data directly.
               In this way buffered streams will cascade harmlessly. */
        flushBuffer();
        out.write(b, off, len);
        return;
    }
    if (len > buf.length - count) {
        flushBuffer();
    }
    // 首先存放到buffer內存中
    System.arraycopy(b, off, buf, count, len);
    count += len;
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72254.html

相關文章

  • Java開發

    摘要:大多數待遇豐厚的開發職位都要求開發者精通多線程技術并且有豐富的程序開發調試優化經驗,所以線程相關的問題在面試中經常會被提到。將對象編碼為字節流稱之為序列化,反之將字節流重建成對象稱之為反序列化。 JVM 內存溢出實例 - 實戰 JVM(二) 介紹 JVM 內存溢出產生情況分析 Java - 注解詳解 詳細介紹 Java 注解的使用,有利于學習編譯時注解 Java 程序員快速上手 Kot...

    LuDongWei 評論0 收藏0
  • JVM實戰---類加載的過程

    任何程序都需要加載到內存才能與CPU進行交流 同理, 字節碼.class文件同樣需要加載到內存中,才可以實例化類 ClassLoader的使命就是提前加載.class 類文件到內存中 在加載類時,使用的是Parents Delegation Model(溯源委派加載模型) Java的類加載器是一個運行時核心基礎設施模塊,主要是在啟動之初進行類的加載、鏈接、初始化 showImg(https://s...

    bladefury 評論0 收藏0
  • Okio 源碼解析(一):數據讀取流程

    摘要:封裝了和,并且有多個優點提供超時機制不需要人工區分字節流與字符流,易于使用易于測試本文先介紹的基本用法,然后分析源碼中數據讀取的流程。和分別用于提供字節流和接收字節流,對應于和。和則是保存了相應的緩存數據用于高效讀寫。 簡介 Okio 是 square 開發的一個 Java I/O 庫,并且也是 OkHttp 內部使用的一個組件。Okio 封裝了 java.io 和 java.nio,...

    senntyou 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<