<java:encoding:dilema/> por Angelos di Avocado

in #spanish7 years ago (edited)
Steemit-Community,

Animado en seguir apoyando la comunidad y como continuación de mis posts instructivos anteriores: <HTML dilema\/> y <HTML:dilema:1.2\>, hoy les traigo como contribución, una forma de detectar formatos o "Encodings" en archivos XMLs usando Java.








Luego de algunas horas de pruebas de conocidos paquetes de fabricantes, como por ejemplo: CharsetDetector (com.ibm.icu.text) y UniversalDetector (org.mozilla.universalchardet), me ví entre la espada y la pared, debido a lo poco efectivas que son estas implementaciones. Fue por ello, que decidí a implementar mi propio código. Veamos como:

Pasos:


  1. convertir los archivos en Inputstream.
  2. Buscar el valor hexadecimal del texto --> "encoding="UTF-8"" y "encoding="UTF-16"", siendo estos los siguientes:
    UTF_8 = "656E636F64696E673D225554462D3822"
    UTF_16 = "65006E0063006F00640069006E0067003D0022005500540046002D003100360022"
  3. Convertir el inputstream en un arreglo de bytes.
  4. Extraer los primeros 200 bytes del archivo
  5. Buscar/comparar si en esos primeros 200 bytes(del paso 3), existe el valor hexadecimal para UTF8 o UTF16 del paso 2.
  6. Heureka

Código:



public class EncodingTest {

    private static String       UTF_8    = "656E636F64696E673D225554462D3822";
    private static String       UTF_16   =
            "65006E0063006F00640069006E0067003D0022005500540046002D003100360022";
    private final static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static InputStream readInputStream(String location) {
        InputStream in = null;
        try {
            in = new FileInputStream(new File(location));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return in;
    }

    public static String testByteEncodingFinder(InputStream inputStream) {
        String ecncodingFormat = null;
        try {
            byte[] bytes = IOUtils.toByteArray(inputStream);
            char[] hexChars = new char[200];
            if (bytes.length > 100)
                for (int i = 0; i < 100; i++) {
                    int v = bytes[i] & 0xFF;
                    hexChars[i * 2] = hexArray[v >>> 4];
                    hexChars[i * 2 + 1] = hexArray[v & 0x0F];
                }
            String text = new String(hexChars);
            if (text.contains(UTF_16)) {
                ecncodingFormat = StandardCharsets.UTF_16.name();
            } else if (text.contains(UTF_8)) {
                ecncodingFormat = StandardCharsets.UTF_8.name();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ecncodingFormat;
    }

    public static void main(String[] args) {
        testByteEncodingFinder(readInputStream("test_279108466.xml"));
        testByteEncodingFinder(readInputStream("Japanese UTF-16.xml"));
    }
}

Espero esta información les sea útil y si tienen algún comentario, siempre sera bienvenido :D

Les invito a seguirme en:
Flicker: https://www.flickr.com/photos/145856611@N05/
@originalworks

Instagram: https://www.instagram.com/diAvokato/

Un saludo virtual.