我想将一个大的字节数组分成小块(比如每64个字节一块)。请帮我实现这个功能。
Damian Vash的第一种方法(使用Arrays.copyOfRange())如果输入的大小不是块大小的整数倍,则向最后一个块末尾添加零。
你也许想使用这种方法代替:
public static List<byte[]> divideArray(byte[] source, int chunksize) {
List<byte[]> result = new ArrayList<byte[]>();
int start = 0;
while (start < source.length) {
int end = Math.min(source.length, start + chunksize);
result.add(Arrays.copyOfRange(source, start, end));
start += chunksize;
}
return result;
}
如果有用的话,同样的操作可以使用ArrayList完成:
public static List<List<String>> divideList(List<String> source, int chunksize) {
List<List<String>> result = new ArrayList<List<String>>();
int start = 0;
while (start < source.size()) {
int end = Math.min(source.size(), start + chunksize);
result.add(source.subList(start, end));
start += chunksize;
}
return result;
}
你可以使用Arrays.copyOfRange(original, from, to)方法
public static byte[][] divideArray(byte[] source, int chunksize) {
byte[][] ret = new byte[(int)Math.ceil(source.length / (double)chunksize)][chunksize];
int start = 0;
for(int i = 0; i < ret.length; i++) {
ret[i] = Arrays.copyOfRange(source,start, start + chunksize);
start += chunksize ;
}
return ret;
}
您也可以像Max建议的那样使用System.arraycopy。
public static byte[][] divideArray(byte[] source, int chunksize) {
byte[][] ret = new byte[(int)Math.ceil(source.length / (double)chunksize)][chunksize];
int start = 0;
for(int i = 0; i < ret.length; i++) {
if(start + chunksize > source.length) {
System.arraycopy(source, start, ret[i], 0, source.length - start);
} else {
System.arraycopy(source, start, ret[i], 0, chunksize);
}
start += chunksize ;
}
return ret;
}
private byte[][] splitChunks(byte[] source)
{
byte[][] ret = new byte[(int)Math.ceil(source.length / (double)CHUNK_SIZE)][];
int start = 0;
for(int i = 0; i < ret.length; i++) {
if(start + CHUNK_SIZE > source.length) {
ret[i] = new byte[source.length-start];
System.arraycopy(source, start, ret[i], 0, source.length - start);
}
else {
ret[i] = new byte[CHUNK_SIZE];
System.arraycopy(source, start, ret[i], 0, CHUNK_SIZE);
}
start += CHUNK_SIZE ;
}
return ret;
}
通常认为System.arraycopy(src, fromPos, dest, toPos, length)比Arrays.copyOfRange更快。
byte[] source = ...read it from somewhere...;
byte[] newArray = new byte[64];
System.arraycopy(source, 0, newArray, 0, 64);
Arrays.copyOfRange
也会分配一个新的数组,而 System.arraycopy
只是将元素复制到作为参数传递的另一个数组中。因此,使用第二种方法可以节省分配时间... 这就是为什么它更快。如果您检查Array.copyOfRange
的定义,您会发现它调用了 System.arraycopy
。 - Jack你有两个选择:
System.arraycopy(...)
Array.copyOfRange(...)
它们两个的工作方式相同,但第一个仅管理复制,而第二个则旨在同时分配新块。
我进行了基准测试,结果表明,如果您在拆分数组之前成功分配所有块,则System.arraycopy
更快,但如果您在复制时分配它们,则略慢,此时应使用Array.copyOfRange
。
这样做就可以了...
byte[] source = new byte[2048];
byte[] target = new byte[1024];
// fill source with some data...
Array.Copy(source, buffer, 1024);
这是使用Arrays.copyOfRange
将字节数组分成块(将“数据”分成blockSize
块)的另一种可能方法:
byte[] data = { 2, 3, 5, 7, 8, 9, 11, 12, 13 };
// Block size in bytes (default: 64k)
int blockSize = 64 * 1024;
int blockCount = (data.length + blockSize - 1) / blockSize;
byte[] range;
try {
for (int i = 1; i < blockCount; i++) {
int idx = (i - 1) * blockSize;
range = Arrays.copyOfRange(data, idx, idx + blockSize);
System.out.println("Chunk " + i + ": " Arrays.toString(range));
}
} finally {
// Last chunk
int end = -1;
if (data.length % blockSize == 0) {
end = data.length;
} else {
end = data.length % blockSize + blockSize * (blockCount - 1);
}
range = Arrays.copyOfRange(data, (blockCount - 1) * blockSize, end);
System.out.println("Chunk " + blockCount + ": " Arrays.toString(range));
}