JDK源碼-InputStream系列

byte

了解InputStream前,我們先了解下byte.

  • byte存在的意義:
    byte,字節,java中一種基本類型.通常在讀取非文本文件(圖片,聲音,可執行文件,網絡通信的數據)需要通過字節數組來保存文件中的內容.
    一個byte占用了8個bit位,所以byte的取值范圍為-128到127.
    內存的最小單元是字節,Intel的X86的芯片內存地址是通過字節編的,指針可以指向的最小內存單元就是一個字節,16位的機器是兩個字節,32位的機器是四個字節.
  • byte的包裝類

byte的包裝類就是Byte,列舉一下常見方法

  • toString(byte b) //靜態的,調用了Integer.toString()
  • ByteCache() //不是很懂,也不是靜態方法啊
  • parseByte(String s) //超過范圍或者不是數字會報:NumberFormatException,調用了Integer.parseInt()
  • valueOf() //把括號里的參數變成Byte對象,超過范圍或者不是數字會報:NumberFormatException
  • byteValue() //返回Byte里的byte
  • shortValue() //返回short,代碼里加了強轉,平時不寫是隱式類型轉換,jvm實現的。
  • intValue(),longValue() //同上
  • floatValue(),doubleValue() //同上,但是不知道精度是否會丟失【TODO】
  • toString() //源碼里調用了Integer.toString,非靜態
  • hashCode() //返回這個類的hashCode
  • equals() //直接比byte了,也不用比hashCode了
  • compareTo(Byte anotherByte) //和另外一個Byte比較大小
  • compare(byte x, byte y) //靜態方法

InputStream

抽象架構圖

InputSteam是所有字節輸入流的實現類的基類.它封裝了流處理類的基本操作.

緩存區字節數組最大值
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
從輸入流中讀取數據的下一個字節,返回int
public abstract int read() throws IOException;
從輸入流中讀取b.length大小的字節,并存儲到字節數組b.
public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

該方法調用了抽象方法:read(),通過該方法獲取流中下一個元素.

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 e) {
        }
        return i;
    }

原始流處理器

接收一個Byte數組對象,或者一個FileDiscriptor對象,一個String對象,或者其他類型的流源對象.
主要一下四種:

ByteArrayInputStream
  • ByteArrayInputStream里的方法基本上都被synchronized關鍵字修飾,所以它是線程安全的.
  • ByteArrayInputStream底層是一個緩沖字節數組
/**
     * An array of bytes that was provided
     * by the creator of the stream. Elements <code>buf[0]</code>
     * through <code>buf[count-1]</code> are the
     * only bytes that can ever be read from the
     * stream;  element <code>buf[pos]</code> is
     * the next byte to be read.
     */
    protected byte buf[];
  • 一般情況下很少使用ByteArrayInputStream,它存在的意義一方面是擴展了InputStream基類,可以通過它賴操作字節數組,另一方面,相當于是其他所有流的一個中間狀態.,用來緩存其他流輸入的數據.
  • 關閉一個字節流是沒有意義的.
/**
     * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
     * this class can be called after the stream has been closed without
     * generating an <tt>IOException</tt>.
     */
    public void close() throws IOException {
    }
FileInputStream

先了解下一些相關類的實現:JDK源碼-File系列

  • FileInputStream用來操作文件流數據,通過構造函數可知,可以通過文件路徑,文件對象,文件描述符對象來創建文件輸入流對象.
public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }

public FileInputStream(File file) throws FileNotFoundException {
        String name = (file != null ? file.getPath() : null);
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(name);
        }
        if (name == null) {
            throw new NullPointerException();
        }
        if (file.isInvalid()) {
            throw new FileNotFoundException("Invalid file path");
        }
        fd = new FileDescriptor();
        fd.attach(this);
        path = name;
        open(name);
    }
public FileInputStream(FileDescriptor fdObj) {
        SecurityManager security = System.getSecurityManager();
        if (fdObj == null) {
            throw new NullPointerException();
        }
        if (security != null) {
            security.checkRead(fdObj);
        }
        fd = fdObj;
        path = null;

        /*
         * FileDescriptor is being shared by streams.
         * Register this stream with FileDescriptor tracker.
         */
        fd.attach(this);
    }
  • FileInputStream的讀取操作和打開文件的操作都是調用本地的native方法.
 /**
     * Opens the specified file for reading.
     * @param name the name of the file
     */
    private native void open0(String name) throws FileNotFoundException;

    // wrap native call to allow instrumentation
    /**
     * Opens the specified file for reading.
     * @param name the name of the file
     */
    private void open(String name) throws FileNotFoundException {
        open0(name);
    }

    /**
     * Reads a byte of data from this input stream. This method blocks
     * if no input is yet available.
     *
     * @return     the next byte of data, or <code>-1</code> if the end of the
     *             file is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public int read() throws IOException {
        return read0();
    }

    private native int read0() throws IOException;
PipedInputStream&PipedOutputStream

PipedInputStream與PipedOutputStream的設計,主要為了實現線程之間可以通過字節流來傳輸數據,來達到通信.

參考文章:Java流編程實例及代碼

StringBufferInputStream

StringBufferInputStream:將一個字符串緩沖區轉換為一個輸入流。接收一個String對象作為流的源。(JDK幫助文檔上說明:已過時。此類未能正確地將字符轉換為字節。從JDK1.1開始,從字符串創建流的首選方法是通過StringReader類進行創建。只有字符串中每個字符的低八位可以由此類使用。)

ObjectInputStream/ObjectOutputStream

詳見JDK源碼-InputStream系列之ObjectOutputStream/ObjectInputStream

鏈接流處理器

FilterInputStream
  • FilterInputStream主要用于包裝一些其他的基本數據的流對象.
  • 該類以及父類,子類的設計對應了裝飾者模式.通過FilterInputStream的代理,所有的子類都可以裝飾一個InputStream類型的對象.這樣,就能夠實現所有裝飾類之間的互相轉換了.
  • FilterInputStream實現了InputStream接口,同樣實現了流處理對象的那一套方法.
BufferedInputStream
  • 它存在的意義是給另外的輸入流添加功能,例如,提供“緩沖功能”以及支持“mark()標記”和“reset()重置方法”。
  • 它的底層實現是一個內部緩存數組.在讀取輸入流的時候,它會分批讀入到緩沖區,當緩沖區中的數據被讀完之后,輸入流會再次填充數據緩沖區.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • tags:io categories:總結 date: 2017-03-28 22:49:50 不僅僅在JAVA領...
    行徑行閱讀 2,220評論 0 3
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,778評論 18 399
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,992評論 19 139
  • 早上為兒子做好早餐送他上學,兒子給我講了昨天在學校發生的事情! 有個女同學交作業時找不到作業本了,她告訴老師:“老...
    繆璘夙閱讀 338評論 0 0
  • 鄧平1閱讀 149評論 0 0