摘要:重要方法一個一個字節讀取,放到數組中重要方法讀取一個字節調用方法讀取的內容調用方法聲明繼承自構造方法從中讀取一個字節歸根究底,目的是將數據放入中緩存,下次讀取可以直接獲取重要方法調用模板方法,由子類實現寫一
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 FilterInputStream1.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 FilterOutputStream2.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
任何程序都需要加載到內存才能與CPU進行交流 同理, 字節碼.class文件同樣需要加載到內存中,才可以實例化類 ClassLoader的使命就是提前加載.class 類文件到內存中 在加載類時,使用的是Parents Delegation Model(溯源委派加載模型) Java的類加載器是一個運行時核心基礎設施模塊,主要是在啟動之初進行類的加載、鏈接、初始化 showImg(https://s...
摘要:封裝了和,并且有多個優點提供超時機制不需要人工區分字節流與字符流,易于使用易于測試本文先介紹的基本用法,然后分析源碼中數據讀取的流程。和分別用于提供字節流和接收字節流,對應于和。和則是保存了相應的緩存數據用于高效讀寫。 簡介 Okio 是 square 開發的一個 Java I/O 庫,并且也是 OkHttp 內部使用的一個組件。Okio 封裝了 java.io 和 java.nio,...
閱讀 3703·2021-11-23 09:51
閱讀 1362·2021-11-10 14:35
閱讀 4009·2021-09-22 15:01
閱讀 1280·2021-08-19 11:12
閱讀 379·2019-08-30 15:53
閱讀 1690·2019-08-29 13:04
閱讀 3429·2019-08-29 12:52
閱讀 3055·2019-08-23 16:14