先给一个需求,给一个字节数组,然后往这个数组中放入各种数据,比如整形,浮点型,字符串等。
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());
输出结果如下:
10
23
1111
3333333
true
a
0.123
10.123
hello 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@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;ichar 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;ireturn 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;ireturn 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());
输出结果如下:
10
23
1111
3333333
true
a
0.123
10.123
hello world!
完美满足需求