Instead of using ByteArrayOutputStream you can allocate a byte[bytes.length] and keep a running len counter. decode() below will take byte[],0,len to decode the buffer. We know we cannot exceed bytes.length as the loop either copies byte-for-byte or collapses 3 bytes to 1 (e.g. "%2F" to "/").