本文最后更新于 1050 天前,其中的信息可能已经有所发展或是发生改变。
在 Android 开发时,有时候会遇到创建 byte 数组的需求。创建 byte 数组和创建其他数组一样,没有什么好稀奇的,但是麻烦的地方在于我负责的项目还在使用 Java 语言,并且由于一些特殊原因不能转为 Kotlin。然而 Java 中数组是不能扩展长度的,因此必须提前设计好数组的长度,然后再进行填充。并且填充数组也非常的麻烦,代码也非常难以阅读,到最后可能也搞不清楚生成的 byte 数组变成什么样了。
因此迫于形势,我只好自己动手,设计一个 ByteArrayBuilder 类,用来组装 byte 数组。其源码如下:
public class ByteArrayBuilder {
private int totalLength = 0;
private final List<ByteArrayEntry> entryList = new LinkedList<>();
public ByteArrayBuilder() {}
public ByteArrayBuilder(byte[] array) {
append(array);
}
public ByteArrayBuilder append(byte value) {
return append(new byte[]{ value });
}
public ByteArrayBuilder append(int value) {
return append((byte) value);
}
public ByteArrayBuilder append(byte[] array) {
return append(array.length, array);
}
public ByteArrayBuilder append(int length, byte value) {
return append(length, new byte[]{ value });
}
public ByteArrayBuilder append(int length, int value) {
return append(length, (byte) value);
}
public ByteArrayBuilder append(int length, byte[] array) {
return append(length, true, array);
}
public ByteArrayBuilder append(int length, boolean isPaddingRight, byte value) {
return append(length, isPaddingRight, new byte[]{ value });
}
public ByteArrayBuilder append(int length, boolean isPaddingRight, int value) {
return append(length, isPaddingRight, (byte) value);
}
public ByteArrayBuilder append(int length, boolean isPaddingRight, byte[] array) {
if (length <= 0) {
// length cannot be negative or zero, ignore
return this;
}
if (length + totalLength < 0) {
// overflow, cannot append, ignore
return this;
}
byte[] data = array;
if (array == null) {
// empty array
data = new byte[0];
}
int srcPosition = 0;
int destPosition = 0;
if (length < data.length) {
// need cut
if (isPaddingRight) {
srcPosition = data.length - length;
}
}
if (length > data.length) {
// need fill
if (isPaddingRight) {
destPosition = length - data.length;
}
}
int copyLength = Math.min(length, data.length);
entryList.add(new ByteArrayEntry(data, length, srcPosition, destPosition, copyLength));
totalLength += length;
return this;
}
public byte[] build() {
byte[] output = new byte[totalLength];
int index = 0;
for (ByteArrayEntry entry : entryList) {
// copy data
System.arraycopy(entry.data, entry.srcPosition, output,
index + entry.destPosition, entry.copyLength);
index += entry.length;
}
return output;
}
private static class ByteArrayEntry {
private final byte[] data;
private final int length;
private final int srcPosition;
private final int destPosition;
private final int copyLength;
public ByteArrayEntry(byte[] data, int length, int srcPosition, int destPosition, int copyLength) {
this.data = data;
this.length = length;
this.srcPosition = srcPosition;
this.destPosition = destPosition;
this.copyLength = copyLength;
}
}
}
这样一套代码可以说非常简单了,基本上不需要任何解释。使用起来也非常简单:
byte[] result = new ByteArrayBuilder()
.append(0x01)
.append(2, 0x02)
.append(new byte[]{0x03, 0x03, 0x03})
.append(4, false, new byte[]{0x04, 0x04})
.build();
// result = {0x01, 0x00, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x00, 0x00}
就是这样。