java字节数组流操作

来源:互联网 发布:win10软件找不到了 编辑:程序博客网 时间:2024/05/16 10:55

需求

先给一个需求,给一个字节数组,然后往这个数组中放入各种数据,比如整形,浮点型,字符串等。

java内置类

java提供了两个流来操作数组,ByteArrayOutputStream和ByteArrayInputStream。然后使用DataOutputStream和DataInputStream流封装一下,就可以写入不同类型的数据。看似满足需求,但是ByteArrayOutputStream这个类并没有传入一个数组的构造方法,只有一个传入一个长度,然后new出一个数组,如下:

 public ByteArrayOutputStream(int size) {        if (size < 0) {            throw new IllegalArgumentException("Negative initial size: " + size);        }        buf = new byte[size];    }

ByteArrayOutputStream写完数据之后,需要转化为数组,方法如下:

 public synchronized byte toByteArray()[] {        return Arrays.copyOf(buf, count);    }

copyOf方法会重新new一个新的数组,如下:

public static byte[] copyOf(byte[] original, int newLength) {        byte[] copy = new byte[newLength];        System.arraycopy(original, 0, copy, 0,                         Math.min(original.length, newLength));        return copy;    }

不仅不满足我们的需求,而且还创建出来两个数组,如果数据比较大的话,还是比较消耗内存。而且一般项目中都有字节缓冲池,一般建议不要擅自创建比较大的数据,一方面是消耗内存,一方面是消耗性能。

我们不妨看一下,实现的方法:

ByteArrayOutputStream baos = new ByteArrayOutputStream(10000);//此处会创建一个数组DataOutputStream dos = new DataOutputStream(baos);dos.writeByte(10);dos.writeShort(23);dos.writeInt(1111);dos.writeLong(3333333);dos.writeBoolean(true);dos.writeChar('a');dos.writeFloat(0.123f);dos.writeDouble(10.123d);dos.writeUTF("hello world!");byte[] byteArray = baos.toByteArray();//此处会创建第二个数组ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);DataInputStream bis = new DataInputStream(bais);System.out.println(bis.readByte());System.out.println(bis .readShort());System.out.println(bis.readInt());System.out.println(bis.readLong());System.out.println(bis.readBoolean());System.out.println(bis.readChar());System.out.println(bis.readFloat());System.out.println(bis.readDouble());System.out.println(bis.readUTF());

输出结果如下:

102311113333333truea0.12310.123hello world!

自定义实现

输出流

import java.io.DataOutput;import java.io.IOException;import java.util.Arrays;public class ByteArrayOutStream implements DataOutput {    /**     * 数组     */    private byte [] buf;    /**     * 下标位置     */    private int index;    public ByteArrayOutStream(byte[] array){        this.buf = array;    }    public ByteArrayOutStream(byte[] array,int offset){        this.buf = array;        this.index = offset;    }    @Override    public void write(int b) throws IOException {        intToBytes(b);    }    @Override    public void write(byte[] b) throws IOException {        if(b == null || b.length == 0){            return;        }        for(byte i : b){            writeByte(i);        }    }    @Override    public void write(byte[] b, int off, int len) throws IOException {        if(b == null || b.length == 0){            return;        }        if(off+len >= b.length){            throw new IOException("传入的数组长度不足");        }        for(int i=off;i<off+len;i++){            writeByte(b[i]);        }    }    @Override    public void writeBoolean(boolean v) throws IOException {        if(v){            writeByte(1);        }else{            writeByte(0);        }    }    @Override    public void writeByte(int v) throws IOException {        this.buf[index] = (byte)v;        indexInc(1);    }    @Override    public void writeShort(int v) throws IOException {        shortToBytes(v);    }    @Override    public void writeChar(int v) throws IOException {        shortToBytes(v);    }    @Override    public void writeInt(int v) throws IOException {        write(v);    }    @Override    public void writeLong(long v) throws IOException {        longToBytes(v);    }    @Override    public void writeFloat(float v) throws IOException {        writeInt(Float.floatToIntBits(v));    }    @Override    public void writeDouble(double v) throws IOException {        writeLong(Double.doubleToLongBits(v));    }    @Override    public void writeBytes(String s) throws IOException {        writeUTF(s);    }    @Override    public void writeChars(String s) throws IOException {        writeUTF(s);    }    @Override    public void writeUTF(String s) throws IOException {        strToBytes(s);    }    private void strToBytes(String s)throws IOException{        int len = s.length();        if(len > 65535){            throw new IOException("字符串长度太长");        }        writeShort(len);        for(int i=0;i<len;i++){            char charAt = s.charAt(i);            writeShort(charAt);        }    }    private void intToBytes(int v) {        for(int i = 0; i < 4; i++) {            buf[index + i] = (byte)(v >>> (24 - i * 8));        }        indexInc(4);    }    private void shortToBytes(int v){        for(int i = 0; i < 2; i++) {            buf[index + i] = (byte)(v >>> (8 - i * 8));        }        indexInc(2);    }    private void longToBytes(long v){        for(int i = 0; i < 8; i++) {            buf[index + i] = (byte)(v >>> (56 - i * 8));        }        indexInc(8);    }    private void indexInc(int inc){        this.index += inc;    }    public String toString(){        return Arrays.toString(buf);    }    public static void main(String ...args)throws Exception{        byte [] array = new byte[10];        ByteArrayOutStream out = new ByteArrayOutStream(array,0);        out.writeInt(2000);        System.out.println(out);    }    public int getIndex() {        return index;    }}

输入流

import java.io.DataInput;import java.io.IOException;public class ByteArrayInStream implements DataInput{    private byte[] buf;    private int index;    private int offset;    private int length;    public ByteArrayInStream(byte[] array){        this.buf = array;    }    public ByteArrayInStream(byte[] array,int offset,int length){        this.buf = array;        this.offset = offset;        this.index = offset;    }    public boolean isAtEnd(){        return index - offset == length;    }    @Override    public void readFully(byte[] b) throws IOException {    }    @Override    public void readFully(byte[] b, int off, int len) throws IOException {    }    @Override    public int skipBytes(int n) throws IOException {        this.index += n;        return this.index;    }    @Override    public boolean readBoolean() throws IOException {        boolean result = false;        if(buf[index] == 1){            result = true;        }        indexInc(1);        return result;    }    @Override    public byte readByte() throws IOException {        byte result = buf[index];        indexInc(1);        return result;    }    @Override    public int readUnsignedByte() throws IOException {        int result = buf[index] & 0xFF;        indexInc(1);        return result;    }    public byte[] readBytes(int len){        byte [] result = new byte[len];        for(int i = index;i<index + len;i++){            result[i-index] = buf[i];        }        return result;    }    @Override    public short readShort() throws IOException {        return bytesToShort();    }    @Override    public int readUnsignedShort() throws IOException {        return bytesToUnsignShort();    }    @Override    public char readChar() throws IOException {        return (char)readShort();    }    @Override    public int readInt() throws IOException {        return bytesToInt();    }    @Override    public long readLong() throws IOException {        return bytesToLong();    }    @Override    public float readFloat() throws IOException {        return Float.intBitsToFloat(readInt());    }    @Override    public double readDouble() throws IOException {        return Double.longBitsToDouble(readLong());    }    @Override    public String readLine() throws IOException {        return readUTF();    }    @Override    public String readUTF() throws IOException {        return bytesToString();    }    private String bytesToString()throws IOException{        int len = readUnsignedShort();        char[] array = new char[len];        for(int i=0;i<len;i++){            array[i] = readChar();        }        return new String(array);    }    private long bytesToLong() {        long num = 0;        for(int i = index; i < index+8; i++) {            num <<= 8;            num |= (buf[i] & 0xff);        }        indexInc(8);        return num;    }    private int bytesToInt() {        int num = 0;        for(int i = index; i < index+4; i++) {            num <<= 8;            num |= (buf[i] & 0xff);        }        indexInc(4);        return num;    }    private short bytesToShort() {        short num = 0;        for(int i = index; i < index+2; i++) {            num <<= 8;            num |= (buf[i] & 0xff);        }        indexInc(2);        return num;    }    private int bytesToUnsignShort() {        int num = 0;        for(int i = index; i < index+2; i++) {            num <<= 8;            num |= (buf[i] & 0xff);        }        indexInc(2);        return num;    }    private void indexInc(int n){        this.index += n;    }}

测试

byte [] array = new byte[10000];//创建一个数组ByteArrayOutStream out = new ByteArrayOutStream(array);out.writeByte(10);out.writeShort(23);out.writeInt(1111);out.writeLong(3333333);out.writeBoolean(true);out.writeChar('a');out.writeFloat(0.123f);out.writeDouble(10.123d);out.writeUTF("hello world!");ByteArrayInStream in = new ByteArrayInStream(array);System.out.println(in.readByte());System.out.println(in.readShort());System.out.println(in.readInt());System.out.println(in.readLong());System.out.println(in.readBoolean());System.out.println(in.readChar());System.out.println(in.readFloat());System.out.println(in.readDouble());System.out.println(in.readUTF());

输出结果如下:

102311113333333truea0.12310.123hello world!

完美满足需求

原创粉丝点击