天天看点

Java IO 其他流 -- 字节数组流,字符数组流和数据流

  1. 字节数组流

    1.1 字节数组输入流ByteArrayInputStream

    参考其源码方法,相对于InputStream,没有新增方法,所以使用也与InputStream一样,可以使用多态,例子如下:

public static void read(byte[] msg) throws IOException {
    InputStream is = new ByteArrayInputStream(msg);
    int len = ;
    byte[] buffer = new byte[];
    while (- != (len = is.read(buffer))) {
        System.out.println(new String(buffer, , len));
    }
    is.close();
}
           

注意:

ByteArrayInputStream中close源码如下,说明字节数组输入流无需关闭,都是存在于内存中,系统会自动释放。

public void close() throws IOException {

}

1.2 字节数组输出流ByteArrayOutputStream

参考其源码方法,相对于OutputStream,有新增方法toByteArray(),所以使用新增方法不能使用多态,例子如下:

public static byte[] write() throws IOException {
    String msg = "节点流--字节数组输出流";
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos.write(msg.getBytes());
    return baos.toByteArray();
}
           

类似于ByteArrayInputStream的close方法,ByteArrayOutputStream也无需手动关闭。

2 字符数组流

字符数组流–CharArrayReader CharArrayWriter

2.1字符输入流 CharArrayReader

可以操作字符数组的输入流,相对于InputStream,也没有新增方法,可以使用多态,例子可参考字节输入流,将ByteArrayInputStream改成CharArrayInputStream即可。

2.2 字符输入流 CharArrayWriter

可以操作字符数组的输出流,相对于OutputStream,有新增方法toCharArray(),使用新增方法时不能使用多态,例子可参考字节输入流,将ByteArrayOutputStream改成CharArrayOutputStream即可。

3 数据流

数据流的读入和写出数据是可以包含数据本身和数据类型。

3.1 数据输入流 DataInputStream

使用DataInputStream读取数据时必须知道写入的顺序,否则会读取失败。

3.2 数据输出流 DataOutputStream

可以写出具体的数据以及数据类型。

3.3 源码比对 如下:

package java.io;

/**
 * A data input stream lets an application read primitive Java data
 * types from an underlying input stream in a machine-independent
 * way. An application uses a data output stream to write data that
 * can later be read by a data input stream.
 * <p>
 * DataInputStream is not necessarily safe for multithreaded access.
 * Thread safety is optional and is the responsibility of users of
 * methods in this class.
 *
 * @author  Arthur van Hoff
 * @see     java.io.DataOutputStream
 * @since   JDK1.0
 */
public class DataInputStream extends FilterInputStream implements DataInput {

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

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

    public final boolean readBoolean() throws IOException {
        int ch = in.read();
        if (ch < )
            throw new EOFException();
        return (ch != );
    }

    public final byte readByte() throws IOException {
        int ch = in.read();
        if (ch < )
            throw new EOFException();
        return (byte)(ch);
    }

    public final int readUnsignedByte() throws IOException {
        int ch = in.read();
        if (ch < )
            throw new EOFException();
        return ch;
    }

    public final short readShort() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        if ((ch1 | ch2) < )
            throw new EOFException();
        return (short)((ch1 << ) + (ch2 << ));
    }

    public final int readUnsignedShort() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        if ((ch1 | ch2) < )
            throw new EOFException();
        return (ch1 << ) + (ch2 << );
    }

    public final char readChar() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        if ((ch1 | ch2) < )
            throw new EOFException();
        return (char)((ch1 << ) + (ch2 << ));
    }

    public final int readInt() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        int ch3 = in.read();
        int ch4 = in.read();
        if ((ch1 | ch2 | ch3 | ch4) < )
            throw new EOFException();
        return ((ch1 << ) + (ch2 << ) + (ch3 << ) + (ch4 << ));
    }

    public final long readLong() throws IOException {
        readFully(readBuffer, , );
        return (((long)readBuffer[] << ) +
                ((long)(readBuffer[] & ) << ) +
                ((long)(readBuffer[] & ) << ) +
                ((long)(readBuffer[] & ) << ) +
                ((long)(readBuffer[] & ) << ) +
                ((readBuffer[] & ) << ) +
                ((readBuffer[] & ) <<  ) +
                ((readBuffer[] & ) <<  ));
    }

    public final float readFloat() throws IOException {
        return Float.intBitsToFloat(readInt());
    }

    public final double readDouble() throws IOException {
        return Double.longBitsToDouble(readLong());
    }

    @Deprecated
    public final String readLine() throws IOException {
        char buf[] = lineBuffer;

        if (buf == null) {
            buf = lineBuffer = new char[];
        }

        int room = buf.length;
        int offset = ;
        int c;

loop:   while (true) {
            switch (c = in.read()) {
              case -:
              case '\n':
                break loop;

              case '\r':
                int c2 = in.read();
                if ((c2 != '\n') && (c2 != -)) {
                    if (!(in instanceof PushbackInputStream)) {
                        this.in = new PushbackInputStream(in);
                    }
                    ((PushbackInputStream)in).unread(c2);
                }
                break loop;

              default:
                if (--room < ) {
                    buf = new char[offset + ];
                    room = buf.length - offset - ;
                    System.arraycopy(lineBuffer, , buf, , offset);
                    lineBuffer = buf;
                }
                buf[offset++] = (char) c;
                break;
            }
        }
        if ((c == -) && (offset == )) {
            return null;
        }
        return String.copyValueOf(buf, , offset);
    }

    public final String readUTF() throws IOException {
        return readUTF(this);
    }

    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*];
                dis.chararr = new char[utflen*];
            }
            chararr = dis.chararr;
            bytearr = dis.bytearr;
        } else {
            bytearr = new byte[utflen];
            chararr = new char[utflen];
        }

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

        in.readFully(bytearr, , utflen);

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

        while (count < utflen) {
            c = (int) bytearr[count] & ;
            switch (c >> ) {
                case : case : case : case : case : case : case : case :
                    /* 0xxxxxxx*/
                    count++;
                    chararr[chararr_count++]=(char)c;
                    break;
                case : case :
                    /* 110x xxxx   10xx xxxx*/
                    count += ;
                    if (count > utflen)
                        throw new UTFDataFormatException(
                            "malformed input: partial character at end");
                    char2 = (int) bytearr[count-];
                    if ((char2 & ) != )
                        throw new UTFDataFormatException(
                            "malformed input around byte " + count);
                    chararr[chararr_count++]=(char)(((c & ) << ) |
                                                    (char2 & ));
                    break;
                case :
                    /* 1110 xxxx  10xx xxxx  10xx xxxx */
                    count += ;
                    if (count > utflen)
                        throw new UTFDataFormatException(
                            "malformed input: partial character at end");
                    char2 = (int) bytearr[count-];
                    char3 = (int) bytearr[count-];
                    if (((char2 & ) != ) || ((char3 & ) != ))
                        throw new UTFDataFormatException(
                            "malformed input around byte " + (count-));
                    chararr[chararr_count++]=(char)(((c     & ) << ) |
                                                    ((char2 & ) << )  |
                                                    ((char3 & ) << ));
                    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, , chararr_count);
    }
}
           

对应的DataOutputStream源码如下,writeXXX()与DataInputStream中的readXXX()与之对应,如下:

package java.io;

public class DataOutputStream extends FilterOutputStream implements DataOutput {

    public synchronized void write(int b) throws IOException {
        out.write(b);
        incCount();
    }

    public synchronized void write(byte b[], int off, int len)
        throws IOException
    {
        out.write(b, off, len);
        incCount(len);
    }

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

    public final void writeBoolean(boolean v) throws IOException {
        out.write(v ?  : );
        incCount();
    }

    public final void writeByte(int v) throws IOException {
        out.write(v);
        incCount();
    }

    public final void writeShort(int v) throws IOException {
        out.write((v >>> ) & );
        out.write((v >>> ) & );
        incCount();
    }

    public final void writeChar(int v) throws IOException {
        out.write((v >>> ) & );
        out.write((v >>> ) & );
        incCount();
    }

    public final void writeInt(int v) throws IOException {
        out.write((v >>> ) & );
        out.write((v >>> ) & );
        out.write((v >>>  ) & );
        out.write((v >>>  ) & );
        incCount();
    }

    public final void writeLong(long v) throws IOException {
        writeBuffer[] = (byte)(v >>> );
        writeBuffer[] = (byte)(v >>> );
        writeBuffer[] = (byte)(v >>> );
        writeBuffer[] = (byte)(v >>> );
        writeBuffer[] = (byte)(v >>> );
        writeBuffer[] = (byte)(v >>> );
        writeBuffer[] = (byte)(v >>>  );
        writeBuffer[] = (byte)(v >>>  );
        out.write(writeBuffer, , );
        incCount();
    }

    public final void writeFloat(float v) throws IOException {
        writeInt(Float.floatToIntBits(v));
    }

    public final void writeDouble(double v) throws IOException {
        writeLong(Double.doubleToLongBits(v));
    }

    public final void writeBytes(String s) throws IOException {
        int len = s.length();
        for (int i =  ; i < len ; i++) {
            out.write((byte)s.charAt(i));
        }
        incCount(len);
    }

    public final void writeChars(String s) throws IOException {
        int len = s.length();
        for (int i =  ; i < len ; i++) {
            int v = s.charAt(i);
            out.write((v >>> ) & );
            out.write((v >>> ) & );
        }
        incCount(len * );
    }

    public final void writeUTF(String str) throws IOException {
        writeUTF(str, this);
    }

    static int writeUTF(String str, DataOutput out) throws IOException {
        int strlen = str.length();
        int utflen = ;
        int c, count = ;

        /* use charAt instead of copying String to char array */
        for (int i = ; i < strlen; i++) {
            c = str.charAt(i);
            if ((c >= ) && (c <= )) {
                utflen++;
            } else if (c > ) {
                utflen += ;
            } else {
                utflen += ;
            }
        }

        if (utflen > )
            throw new UTFDataFormatException(
                "encoded string too long: " + utflen + " bytes");

        byte[] bytearr = null;
        if (out instanceof DataOutputStream) {
            DataOutputStream dos = (DataOutputStream)out;
            if(dos.bytearr == null || (dos.bytearr.length < (utflen+)))
                dos.bytearr = new byte[(utflen*) + ];
            bytearr = dos.bytearr;
        } else {
            bytearr = new byte[utflen+];
        }

        bytearr[count++] = (byte) ((utflen >>> ) & );
        bytearr[count++] = (byte) ((utflen >>> ) & );

        int i=;
        for (i=; i<strlen; i++) {
           c = str.charAt(i);
           if (!((c >= ) && (c <= ))) break;
           bytearr[count++] = (byte) c;
        }

        for (;i < strlen; i++){
            c = str.charAt(i);
            if ((c >= ) && (c <= )) {
                bytearr[count++] = (byte) c;

            } else if (c > ) {
                bytearr[count++] = (byte) ( | ((c >> ) & ));
                bytearr[count++] = (byte) ( | ((c >>  ) & ));
                bytearr[count++] = (byte) ( | ((c >>  ) & ));
            } else {
                bytearr[count++] = (byte) ( | ((c >>  ) & ));
                bytearr[count++] = (byte) ( | ((c >>  ) & ));
            }
        }
        out.write(bytearr, , utflen+);
        return utflen + ;
    }

    public final int size() {
        return written;
    }
}