I would like to divide a large byte array into smaller chunks (say 64 bytes). Please help me with this.
8 Answers
Damian Vash's first method (the one using Arrays.copyOfRange()) adds zeros to the end of the last chunk if the input is not exactly a multiple of chunksize.
You might want to use this instead:
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;
}
and in case it's useful, the same thing using ArrayList's:
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;
}

- 62,887
- 36
- 269
- 388

- 542
- 4
- 7
You can use the method 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;
}
Or You can use as Max suggested the 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;
}

- 8,932
- 2
- 41
- 54

- 30,365
- 9
- 60
- 95
-
2Beware that the second of these appears to allocate a "too large" of last chunk if source.length is not an even multiple of the chunksize... – rogerdpack May 06 '15 at 23:45
-
-
@VishalPatoliyaツ Just pass as chunk size 5000000 bytes. As 5MB = 5 Million Bytes. – Gaurav Mall Jul 31 '19 at 12:08
If you are looking save some memory, a slight modification to Damian Vash's answer would help (in this case any remaining chunk is not allocated a complete 64 byte block size, as well...)
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;
}

- 62,887
- 36
- 269
- 388

- 995
- 6
- 16
- 37
Well, System.arraycopy(src, fromPos, dest, toPos, length) is generally considered faster than Arrays.copyOfRange.
byte[] source = ...read it from somewhere...;
byte[] newArray = new byte[64];
System.arraycopy(source, 0, newArray, 0, 64);

- 25,562
- 10
- 53
- 84
-
4This is incorrect: it's not a matter of being faster, `Arrays.copyOfRange` also allocates a new `array` while `System.arraycopy` just copy elements in another `array` passed as parameter. So with second one you save the allocation.. that's why it is faster. If you check the definition of `Array.copyOfRange` you will see that it invokes `System.arraycopy`.. – Jack Aug 04 '10 at 12:41
You have two choices:
System.arraycopy(...)
Array.copyOfRange(...)
both of them work the same way but while first one only manages copy, second one is meant to be used to allocate the new chunk at the same time.
I benchmarked them with a result that System.arraycopy
is faster if you manage to allocate chunks all together before splitting your array but slightly slower if you allocate them whle you copy: in this case you should use Array.copyOfRange
.

- 131,802
- 30
- 241
- 343
-
Very interesting benchmark given that Array.copyOfRange() calls System.arraycopy: http://pastebin.com/SpSyx8Cd – bezmax Aug 04 '10 at 12:56
See Arrays.copyOfRange for help. You could use this in a loop to split your array into several smaller chunks.

- 1,790
- 1
- 15
- 34
This is another possible way of using Arrays.copyOfRange
to divide a byte array in chunks (splitting the "data" in blockSize
chunks):
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));
}

- 131
- 7
This will do...
byte[] source = new byte[2048];
byte[] target = new byte[1024];
// fill source with some data...
Array.Copy(source, buffer, 1024);

- 127
- 2
- 11