es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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);
    }
Tags:  , , , ,

Answer

  1. Avatar for 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étodo map para extraer subcadenas hexadecimales de dos dígitos de la cadena hexadecimal de entrada, y finalmente utilizar el método mapToInt para convertir cada subcadena de dos dígitos en un valor de byte utilizando Integer.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étodo toArray.

    Aquí hay un ejemplo de implementación:

    public static byte[] hexStringToBytesStream(String hexString) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Cadena hexadecimal para convertir a byte[] " + hexString);
        }
        return IntStream.range(0, hexString.length() / 2)
                .mapToObj(i -> hexString.substring(2 * i, 2 * i + 2))
                .mapToInt(s -> Integer.parseInt(s, HEX_RADIX))
                .mapToByte(n -> (byte) n)
                .toArray();
    }
    

    Ten en cuenta que el método mapToByte se utiliza para convertir cada valor int en un valor byte de manera compacta. Además, esta implementación evita el uso de un bucle for 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.

Comments are closed.