¿Existe alguna forma de convertir una cadena hexadecimal en bytes utilizando flujos de Java?
El fragmento de código a continuación, a largo plazo, siempre produce un error de Out-Of-Memory, especialmente al leer de un archivo / contenido muy voluminoso.
¿Hay otra forma de volver a escribir esto, especialmente usando streams?
Vi una forma de convertir una matriz de bytes en una cadena hexadecimal aquí: https://stackoverflow.com/questions/27181383/effective-way-to-get-hex-string-from-a-byte-array-using-lambdas-and-streams/70248035#70248035
public static byte[] hexStringToBytes(String hexString) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Cadena hexadecimal para convertir en byte[] " + hexString);
}
byte[] buf = new byte[hexString.length() / 2];
String twoDigitHexToConvertToByte;
for (int i = 0; i < buf.length; i++) {
twoDigitHexToConvertToByte = extractPairFromStringBasedOnIndex(hexString, i);
parseStringToBytesAndStoreInArrayOnIndex(twoDigitHexToConvertToByte, buf, i);
}
return buf;
}
private static void parseStringToBytesAndStoreInArrayOnIndex(String twoDigitHexToConvertToByte, byte[] buf, int i) {
try {
buf[i] = (byte) Integer.parseInt(twoDigitHexToConvertToByte, HEX_RADIX);
} catch (NumberFormatException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.info("Intentó convertir una cadena no hexadecimal:", e);
} else {
LOGGER.info("Intentó convertir una cadena no hexadecimal: " + e.getMessage());
}
throw new HexStringToBytesException("Intentó convertir una cadena no hexadecimal"); // NOSONAR xlisjov no quiero la causa original ya que causó excepciones.
}
}
private static String extractPairFromStringBasedOnIndex(String hexString, int pairNumber) {
return hexString.substring(2 * pairNumber, 2 * pairNumber + 2);
}
davy.ai
Sí, hay otra manera de reescribir esto utilizando streams.
Una posible forma es utilizar el método
IntStream.range
para generar un stream de índices, luego utilizar el métodomap
para extraer subcadenas hexadecimales de dos dígitos de la cadena hexadecimal de entrada, y finalmente utilizar el métodomapToInt
para convertir cada subcadena de dos dígitos en un valor de byte utilizandoInteger.parseInt
con el argumento de la base establecido en 16. El stream resultante de valores de byte se puede recopilar en un arreglo de bytes utilizando el métodotoArray
.Aquí hay un ejemplo de implementación:
Ten en cuenta que el método
mapToByte
se utiliza para convertir cada valorint
en un valorbyte
de manera compacta. Además, esta implementación evita el uso de un buclefor
y variables intermedias, en cambio utiliza el encadenamiento de métodos para crear una tubería de procesamiento de streams que es más concisa y fácil de leer.