How can I replace a subarray of a byte array?
I need something similar with replace method for strings:
"I want pizza".replace("pizza", "replace method for byte arrays")
but it should work for byte[].
Assuming you want to replace an n-byte subarray with another n-byte subarray, you can use System.arraycopy.
For example:
System.arraycopy(theNewBytes, startPosition,
theArrayYouWantToUpdate, startPosition1, length);
If you want to replace n bytes with some different number of bytes, you would need to create a new array anyway:
arrayCopyIt is possible to use the power of the almighty String to do this :)
static byte[] replace(byte[] src, byte[] find, byte[] replace) {
String replaced = cutBrackets(Arrays.toString(src))
.replace(cutBrackets(Arrays.toString(find)), cutBrackets(Arrays.toString(replace)));
return Arrays.stream(replaced.split(", "))
.map(Byte::valueOf)
.collect(toByteArray());
}
private static String cutBrackets(String s) {
return s.substring(1, s.length() - 1);
}
private static Collector<Byte, ?, byte[]> toByteArray() {
return Collector.of(ByteArrayOutputStream::new, ByteArrayOutputStream::write, (baos1, baos2) -> {
try {
baos2.writeTo(baos1);
return baos1;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}, ByteArrayOutputStream::toByteArray);
}
Using custom Collector.toByteArray from this answer
Test results:
byte[] arr = {10, 20, 30, 40, 50, 51, 52, 53, 54, 62, 63};
byte[] find = {10, 20, 30};
byte[] replace = {21, 22, 23, 31, 32, 33};
System.out.println(Arrays.toString(replace(arr, find, replace)));
Output:
[21, 22, 23, 31, 32, 33, 40, 50, 51, 52, 53, 54, 62, 63]
Arrays.toString() works fineString.replace actually invokes replaceAll, after quoting its arguments. You can reasonably easily implement an indexOf method that finds the start position of a subarray in another array (fancy algorithms exist, but String.indexOf is actually naive); then use System.arrayCopy.
new String(bytes)and pray it will work, then use String'sreplace()with Strings built in the same way, then get back your bytes withstr.getBytes(). But with an image file, I think you will run into illegal byte sequences for pretty much any String encoding, so that's likely unsafe.