Internacionalización de Programas Java

En el lenguaje de programaci�n Java, los valores char representan caracteres Unicode. Unicode es una codificaci�n de caracteres de 16 bits que soporta la mayor�a de los idiomas del mundo. Podr�s aprender m�s sobre el est�ndard Unicode en la web site de Unicode Consortium.

Pocos editores de texto soportan actualmente texto Unicode. El editor de texto que hemos utilizado para escribir los c�digos de ejemplo de esta lecci�n s�lo soporta caracteres ASCII, que est�n limitados a 7 bits. Para indicar un caracter Unicode que no puede ser representado en ASCII, como "�," hemos utilizado la secuencia de escape '\udddd'. Cada "d" en la secuencia de escape es un d�gito hexadecimal. El siguiente ejemplo muestra c�mo indicar el caracter "�" con una secuencia de escape.

String str = "\u00F6";
char c = '\u00F6';
Character letter = new Character('\u00F6');

No tenemos que especificar al secuencia de escape Unicode para caracteres ASCII. Cuando se leen ficheros ASCII o ISO Latin-1, el entorno de ejecuci�n de Java convierte autom�ticamente los caracteres a Unicode. Sin embargo, si se quiere convertir texto desde otras codificaciones a Unicode, debemos realizar las conversiones nosotros mismos.

En esta lecci�n se explica el API que se utiliza para traducir texto no-Unicode a Unicode. Antes de utilizar estos APIs, deber�amos verificar que la codificaci�n que queremos convertir est� soportada. La lista de codificaciones soportadas no forma parte de la especificaci�n del lenguaje de programaci�n Java. Por lo tanto, podr�a variar con las plataformas. Para ver las codificaciones soportadas por el JDK, puedes ver la secci�n "Supported Encodings" en la documentaci�n Internationalization Overview.

Las siguientes secciones describen dos t�cnicas para convertir texto no-Unicode.

.�Bytes Codificados y Strings

Esta secci�n muestra c�mo convertir arrays de bytes no-Unicode en objetos Strings, y vice-versa.

Si el texto no-Unicode est� almacenado en un array de bytes, se pueden convertir a Unicode con uno de los m�todos constructores de String. Inversamente, se puede convertir un objeto String en un array de bytes de caracters no-Unicode con el m�todo String.getBytes. Cuando se llama a estos m�todos se debe especificar el identificador de la codificaci�m como uno de los par�metros.

En los siguientes ejemplos convertiremos caracteres entre UTF8 y Unicode. UTF8 es una forma binaria compacta para codificar caracteres Unicode de 16-bits en 8 bits. El c�digo fuente de este ejemplo est� en el fichero llamado StringConverter.java.

Primero creamos un String que contiene los caracteres Unicode.

String original = new String("A" + "\u00ea" + "\u00f1"
                                 + "\u00fc" + "C");

Cuando imprimimos el String llamado original aparecer� como.


A���C

Para convertir el objeto String a UTF8, llamamos al m�todo getBytes y le especificamos el identificador de codificaci�n apropiado como un par�metro. El m�todo getBytes devuelve un array de bytes en formato UTF8. Para crear un objeto String desde un array de bytes no-Unicode, llamamos al constructor de String con el par�metro de la codificaci�n, El c�digo que hace est�s llamadas est� encerrado en un bloque try, para el caso de que la codificaci�n especificada no estuviera soportada.

try {
   byte[] utf8Bytes = original.getBytes("UTF8");
   byte[] defaultBytes = original.getBytes();

   String roundTrip = new String(utf8Bytes, "UTF8");
   System.out.println("roundTrip = " + roundTrip);

   System.out.println();
   printBytes(utf8Bytes, "utf8Bytes");
   System.out.println();
   printBytes(defaultBytes, "defaultBytes");
   }
catch (UnsupportedEncodingException e) {
   e.printStackTrace();
}

Imprimimos los valores de los arrays utf8Bytes y defaultBytes para demostrar un punto importante. La longitud del texto convertido podr�a no ser la misma que la longitud del texto original. Algunos caracteres Unicode se traducen en bytes sencillos, y otros en parejas de bytes. Nuestra rutina para mostrar los arrays de bytes es esta.


public static void printBytes(byte[] array, String name) {
   for (int k = 0; k < array.length; k++) {
      System.out.println(name + "[" + k + "] = " + "0x" +
         UnicodeFormatter.byteToHex(array[k]));

   }
}

Aqu� est� la salida de los m�todos printBytes. Observa que s�lo el primer y �ltimo caracteres la "A" y la "C", son los mismos en los dos arrays.

utf8Bytes[0] = 0x41
utf8Bytes[1] = 0xc3
utf8Bytes[2] = 0xaa
utf8Bytes[3] = 0xc3
utf8Bytes[4] = 0xb1
utf8Bytes[5] = 0xc3
utf8Bytes[6] = 0xbc
utf8Bytes[7] = 0x43

defaultBytes[0] = 0x41
defaultBytes[1] = 0xea
defaultBytes[2] = 0xf1
defaultBytes[3] = 0xfc
defaultBytes[4] = 0x43

.�Streams de Caracteres y de Bytes

En esta secci�n aprender�s como traducir entre streams de caracteres Unicode y streams de bytes con texto no-Unicode.

El paquete java.io proporciona clases que permiten conversiones entre streams de caracteres y streams de bytes de texto no-Unicode. Con la clase InputStreamReader, se pueden convertir streams de bytes a streams de caracteres. Se utiliza la clase OutputStreamWriter para traducir streams de caracteres a streams de bytes.

Cuando se crean objetos InputStreamReader y OutputStreamWriter, se debe especificar la codificaci�n que se quiere convertir. Por ejemplo, si queremos traducir un fichero de texto en formato UTF8 a Unicode, deber�amos crear un InputStreamReader de la siguiente forma.

FileInputStream fis = new FileInputStream("output.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF8");

Si se omite el identificador de codificaci�n, InputStreamReader y OutputStreamWriter utilizar�n la codificaci�n por defecto. Al igual que la lista de codificaciones soportadas, la codificaci�n por defecto puede variar con la plataforma Java. En la versi�n 1.1 del JDK, la codificaci�n por defecto es 8859_1 (ISO-Latin-1). Este valor se selecciona en la propiedad del sistema file.encoding. Puedes determinar la codificaci�n que utilizar� un InputStreamReader o un OutputStreamWriter llamando al m�todo getEncoding. En el siguiente ejemplo, llamamos al m�todo para determinar que la codificaci�n por defecto de nuestra plataforma sea 8859_1.

InputStreamReader defaultReader = new InputStreamReader(fis);
System.out.println(defaultReader.getEncoding());

Se espec�fica un InputStream cuando se crea un InputStreamReader, y un OutputStream cuando se construye un OutputStreamWriter. InputStream y OutputStream son superclases abstractas y todas sus entradas y salidas son streams de bytes, Esto pemite realizar conversiones de cualquiera de los streams de bytes que pertenezcan a sus subclases. Por ejemplo, con un InputStreamReader se puede convertir texto no-Unicode desde un FileInputStream o un PipedInputStream, porque ambas son subclases de InputStream.

En el siguiente ejemplo. veremos como realizar conversiones con las clases InputStreamReader y OutputStreamWriter. El c�digo fuente de este ejemplo lo puedes encontrar en el fichero StreamConverter.java. En este ejemplo, convertimos una secuencia de caracteres Unicode desde un objeto String en un FileOutputStream de bytes codificado en UTF8. El m�todo que realiza la conversi�n se llama writeOutput.

static void writeOutput(String str) {

    try {
       FileOutputStream fos = new FileOutputStream("output.txt");
       Writer out = new OutputStreamWriter(fos, "UTF8");
       out.write(str);
       out.close();
    } 
    catch (IOException e) {
       e.printStackTrace();
    }
}

En otro m�todo, readInput, leemos los bytes codificados en UTF8 desde el fichero creado con el m�todo writeOutput. Utilizamos un InputStreamReader para convertir los bytes de UTF8 a Unicode, y devolver el resultado en un String. Aqu� puedes ver el m�todo readInput.

static String readInput() {

   StringBuffer buffer = new StringBuffer();
   try {
      FileInputStream fis = new FileInputStream("output.txt");
      InputStreamReader isr = new InputStreamReader(fis, "UTF8");
      Reader in = new BufferedReader(isr);
      int ch;
      while ((ch = in.read()) > -1) {
         buffer.append((char)ch);
      }
      in.close();
      return buffer.toString();
   } 
   catch (IOException e) {
      e.printStackTrace();
      return null;
   }
}

En el m�todo main de nuestro programa ejemplo, llamamos al m�todo writeOutput para crear un fichero de bytes codificado en UTF. Luego leemos el mismo fichero, convirtiendo de nuevo los bytes a Unicode. Aqu� puedes ver el c�digo del m�todo main.

public static void main(String[] args) {

   String jaString  = 
      new String("\u65e5\u672c\u8a9e\u6587\u5b57\u5217");

   writeOutput(jaString);
   String inputString = readInput();
   String displayString = jaString + " " + inputString;
   new ShowString(displayString, "Conversion Demo");
}

La cadena original (jaString) deber�a ser id�ntica a la recien creada (inputString). Para ver si las dos cadenas son iguales, las concatenamos y las mostramos con un objeto ShowString. La clase ShowString muestra un string con el m�todo Graphics.drawString. El c�digo fuente de esta clases est� en el fichero ShowString.java. Cuando ejemplarizamos un ShowString en nuestro programa ejemplo, aparecen las siguientes ventanas. La repetici�n de los caracteres mostrados verifica que las dos cadenas son id�nticas.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP