java.io DataInputStream與DataOutputStream理解(三)

DataInputStream與DataOutputStream類都是流的裝飾者類(java中流的設計採用了裝飾者模式),它是用來裝飾其它基本的輸入流的,比如FileInputStream、ByteArrayInputStream等。首先理解DataInputStream。
DataInputStream類,java的註釋是“它允許應用程序以與機器無關方式從底層輸入流中讀取基本的java數據類型”。也就是說,通過DataInputStream類可以從被裝飾的輸入流類(FileInputStream、ByteArrayInputStream)中讀取java基本數據類型。DataInputStream中的read、readByte、readDouble、readInt等方法比較簡單,容易理解。重點理解readUTF方法,源碼如下:

//將utf編碼的輸入流中字節轉換爲字符串,要想看懂這個方法的代碼,需要了解utf-8編碼//原理,如果不想深入理解,只要知道這個方法就是將輸入流的字節數組按照utf-8編碼方//式轉換成字符串
public final static String readUTF(DataInput in) throws IOException {
        int utflen = in.readUnsignedShort();
        byte[] bytearr = null;
        char[] chararr = null;
        if (in instanceof DataInputStream) {
            DataInputStream dis = (DataInputStream)in;
            if (dis.bytearr.length < utflen){
                dis.bytearr = new byte[utflen*2];
                dis.chararr = new char[utflen*2];
            }
            chararr = dis.chararr;
            bytearr = dis.bytearr;
        } else {
            bytearr = new byte[utflen];
            chararr = new char[utflen];
        }

        int c, char2, char3;
        int count = 0;
        int chararr_count=0;

        in.readFully(bytearr, 0, utflen);

        while (count < utflen) {
            c = (int) bytearr[count] & 0xff;
            if (c > 127) break;
            count++;
            chararr[chararr_count++]=(char)c;
        }

        while (count < utflen) {
            c = (int) bytearr[count] & 0xff;
            switch (c >> 4) {
                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                    /* 0xxxxxxx*/
                    count++;
                    chararr[chararr_count++]=(char)c;
                    break;
                case 12: case 13:
                    /* 110x xxxx   10xx xxxx*/
                    count += 2;
                    if (count > utflen)
                        throw new UTFDataFormatException(
                            "malformed input: partial character at end");
                    char2 = (int) bytearr[count-1];
                    if ((char2 & 0xC0) != 0x80)
                        throw new UTFDataFormatException(
                            "malformed input around byte " + count);
                    chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
                                                    (char2 & 0x3F));//
                    break;
                case 14:
                    /* 1110 xxxx  10xx xxxx  10xx xxxx */
                    count += 3;
                    if (count > utflen)
                        throw new UTFDataFormatException(
                            "malformed input: partial character at end");
                    char2 = (int) bytearr[count-2];
                    char3 = (int) bytearr[count-1];
                    if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
                        throw new UTFDataFormatException(
                            "malformed input around byte " + (count-1));
                    chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
                                                    ((char2 & 0x3F) << 6)  |
                                                    ((char3 & 0x3F) << 0));
                    break;
                default:
                    /* 10xx xxxx,  1111 xxxx */
                    throw new UTFDataFormatException(
                        "malformed input around byte " + count);
            }
        }
        // The number of chars produced may be less than utflen
        return new String(chararr, 0, chararr_count);
    }

DataOutputStream是應用程序將java基本類型數據寫入到輸出流中。例如將java基本類型寫入到文件、字節數組等容器中。DataOutputStream繼承FilterOutputStream,是裝飾者類,用來裝飾基本的輸出流類,如FileOutputStream、ByteArrayInputStream。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章