I ended up writing my own method which uses a temporary fixed buffer array and appends it to your final byte array each time after the fixed buffer is filled. It will continue to overwrite the fixed buffer array and append to your final array until all bytes are read and copied. At the end, if the temporaryArray is not filled, it will copy the read bytes from that array into the final array. My code was written for Android, so you may need to use a similar method to ArrayUtils.concatByteArrays
(com.google.gms.common.util.ArrayUtils)
My code has the temporary array size set to 100 (growBufferSize) but it might be better to set above 500 or even 1000 or whatever performs best on the environment you use. The final result will be stored in the bytesfinal array.
This method should reduce memory usage to prevent OutOfMemoryError s. Since it is using mainly primitives, memory should be reduced.
final int growBufferSize = 100;
byte[] fixedBuffer = new byte[growBufferSize];
byte[] bytesfinal = new byte[0];
int fixedBufferIndex=0;
while (zin.available()>0){
fixedBuffer[fixedBufferIndex] = (byte)zin.read();
if (fixedBufferIndex == growBufferSize-1){
bytesfinal = ArrayUtils.concatByteArrays(bytesfinal,fixedBuffer);
fixedBufferIndex = -1;
}
fixedBufferIndex++;
}
if (fixedBufferIndex!=0){
byte[] lastBytes = new byte[fixedBufferIndex];
//copy last read bytes to new array
for (int i = 0; i<fixedBufferIndex; i++){
lastBytes[i]=fixedBuffer[i];
}
//add last bits of data
bytesfinal = ArrayUtils.concatByteArrays(bytesfinal,lastBytes);
lastBytes = null;
fixedBuffer = null;
}
public class ArrayUtils {
static byte[] concatByteArrays(byte[] first, byte[] second) {
byte[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
}