¿Por qué la conversión de UTF-8 a ISO-8859-1 no es la misma en Windows y Linux?

Tengo el siguiente código para convertir de UTF-8 a ISO-8859-1 en un archivo jar y cuando ejecuto este jar en Windows obtengo un resultado y en CentOS obtengo otro. ¿Alguien sabe por qué?

public static void main(String[] args) {

  try {

    String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";

    Charset utf8charset = Charset.forName("UTF-8");
    Charset iso88591charset = Charset.forName("ISO-8859-1");

    ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes());
    CharBuffer data = utf8charset.decode(inputBuffer);

    ByteBuffer outputBuffer = iso88591charset.encode(data);
    byte[] outputData = outputBuffer.array();

    String z = new String(outputData);

    System.out.println(z);
  }
  catch(Exception e) {
    System.out.println(e.getMessage());
  }
}

En Windows, java -jar test.jar> test.txt crea un archivo que contiene: Ä, ä, É, é, Ö, ö, Ü, ü, ß, «,»

pero en CentOS obtengo: ?, ä, ?, é, ?, ö, ?, ü, ?, «,»

Respuesta 1

En primer lugar, debe obtener la cadena en la representación interna correcta en Java antes de siquiera pensar en la salida. IE debería ser que:

z.equals("Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »") == true

Lo anterior se puede verificar sin problemas de codificación de salida, ya que simplemente imprime trueo false.

En Windows ya lo lograste con

ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes());
CharBuffer data = utf8charset.decode(inputBuffer);

Porque todo lo que necesita para ir "Ä, ä, É, é, Ö, ö, Ãœ, ü, ß, «, »"a "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »"es:

ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes( windows1252/*explicit windows1252 works on CentOS too*/));
CharBuffer data = utf8charset.decode(inputBuffer);

Después de esto, hace algo con ISO-8859-1, lo cual es inútil porque apenas la mitad de los caracteres en su cadena original se pueden representar en ISO-8859-1, sin mencionar que ya lo hizo como se indicó anteriormente. Puedes borrar el código despuésutf8charset.decode(inputBuffer)

Entonces, su código podría verse así:

String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";

Charset windows1252 = Charset.forName("Windows-1252");
Charset utf8charset = Charset.forName("UTF-8");

byte[] bytes = x.getBytes(windows1252);
String z = new String(bytes, utf8charset);

                                //Still wondering why you didn't just have this literal to begin with
                                //Check that the strings are internally equal so you know at least that
                                //the code is working

System.out.println(z.equals( "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »")); 
System.out.println(z);
Respuesta: 2

Soy nuevo en Java y sigo recibiendo este mensaje de error: no se puede acceder a ninguna instancia adjunta del tipo Managesalary. Debe calificar la asignación con una instancia adjunta del tipo Managesalary (egx ...

Tengo una clase genérica Foo <T> y tipos parametrizados Foo <String> y Foo <Integer>. Ahora quiero poner diferentes tipos parametrizados en una sola ArrayList. Cuál es la manera correcta ...

Estoy usando JPBM para diseñar un flujo de proceso, con BPMN2. Quiero crear una instancia de un objeto de clase en una Tarea de script, por ejemplo: Map <String, Object> params = new HashMap <String, Object> (); ...

Soy bastante nuevo en Guava API y estoy tratando de ordenar las claves de un MultiMap en orden inverso o valor descendente. Estoy iniciando el mapa de la siguiente manera: ListMultimap <Fecha, Mapa <Cadena, Cadena y ...