2008-12-15 25 views
16

Necesito escribir una utilidad 'simple' para convertir de ASCII a EBCDIC?¿Convertir cadena de ASCII a EBCDIC en Java?

El Ascii viene de Java, Web y va a un AS400. He tenido un google alrededor, parece que no puedo encontrar una solución fácil (tal vez porque no hay uno :(). Esperaba una utilidad opensource o una utilidad paga que ya se ha escrito.

como esto tal vez?

Converter.convertToAscii(String textFromAS400) 
Converter.convertToEBCDIC(String textFromJava) 

Gracias,

de Scott

+0

¿Tiene que lidiar con redefiniciones y registros empaquetados, o se trata de una transacción directa? – kemiller2002

Respuesta

10

JTOpen, la versión de código abierto de IBM de su caja de herramientas Java tiene una colección de clases para acceder a AS/400 objetos, entre ellos un FileReader y FileWriter acceder a archivos de texto AS400 nativos. Eso puede ser más fácil de usar que escribir sus propias clases de conversión.

Desde la página principal JTOpen:

Éstos son sólo algunos de los muchos i5/OS y/OS 400 recursos se puede acceder utilizando JTOpen:

  • base de datos - JDBC (SQL) y el acceso a nivel de registro (DDM)
  • sistema de archivos integrado
  • programa llama
  • Comandos
  • Colas de datos
  • Áreas de datos
  • recursos
  • Imprimir/carrete
  • del producto y la información de PTF
  • Los trabajos y los registros de trabajos
  • mensajes, colas de mensajes, archivos de mensajes
  • Usuarios y grupos
  • usuario espacios
  • Valores del sistema
  • Estado del sistema
+0

Estamos usando la caja de herramientas JTopen y está haciendo algo de la conversión/mapeo, simplemente parece mapear incorrectamente £, $, [y^ – scottyab

+1

Parece que su AS/400 está configurado incorrectamente con respecto a su lengua materna. Si está configurado correctamente, jt400.jar no requerirá ningún otro ajuste. –

+0

Sí, la conversión debería realizarse de manera básicamente automática. Si no es así, algo no está configurado correctamente. –

0

debe ser bastante fácil de escribir un mapa para el juego de caracteres EBCDIC, y uno para el juego de caracteres ASCII, y en cada retorno de la Representación de personajes del otro. Luego simplemente haz un bucle sobre la cuerda para transl comió, y busca cada carácter en el mapa y lo agrega a una cadena de salida.

No sé si hay algún convertidor disponible públicamente, pero no debería tomar más de una hora escribir uno.

1

Puede crear uno con este translation table.

Pero here es un sitio que tiene un enlace a un ejemplo de Java.

+1

El segundo enlace está muerto. ¿Sabes dónde fue? ¿Puedes publicar el ejemplo aquí? –

2

Debe usar el juego de caracteres Java Cp1047 (Java 5) o Cp500 (JDK 1.3+).

utilizar el constructor de la secuencia: String(byte[] bytes, [int offset, int length,] String enc)

+0

Olvidó Cp037 (tenemos ese). Debe sugerir que la persona verifique qué juego de caracteres se está utilizando. –

28

Tenga en cuenta que una cadena en Java contiene texto en la codificación nativa de Java. Cuando mantiene una "cadena" ASCII o EBCDIC en la memoria, antes de codificar como una Cadena, la tendrá en un byte [].

 
ASCII -> Java: new String(bytes, "ASCII") 
EBCDIC -> Java: new String(bytes, "Cp1047") 
Java -> ASCII: string.getBytes("ASCII") 
Java -> EBCDIC: string.getBytes("Cp1047") 
+4

Hay muchas tablas de códigos EBCDIC. Es muy tedioso arreglarse manualmente. –

+1

Los juegos de caracteres de Java que comienzan con "CP" hacen referencia a los CCSID de IBM. Parte de la documentación de estos se puede encontrar en http://www-03.ibm.com/systems/i/software/globalization/ccsid_list.html y http://www-03.ibm.com/systems/i/software/ globalization/codepages.html CP1047 parece referirse a 01047, "Latin 1/Open Systems". –

+0

@AlanKrueger a partir de hoy estos enlaces están muertos. Eso es realmente muy malo. –

0

Esto es lo que he estado usando.

public static final int[] ebc2asc = new int[256]; 
public static final int[] asc2ebc = new int[256]; 

static 
{ 
    byte[] values = new byte[256]; 
    for (int i = 0; i < 256; i++) 
    values[i] = (byte) i; 

    try 
    { 
    String s = new String (values, "CP1047"); 
    char[] chars = s.toCharArray(); 
    for (int i = 0; i < 256; i++) 
    { 
     int val = chars[i]; 
     ebc2asc[i] = val; 
     asc2ebc[val] = i; 
    } 
    } 
    catch (UnsupportedEncodingException e) 
    { 
    e.printStackTrace(); 
    } 
} 
3
package javaapplication1; 

import java.nio.ByteBuffer; 
import java.nio.CharBuffer; 

import java.nio.charset.CharacterCodingException; 

import java.nio.charset.Charset; 

import java.nio.charset.CharsetDecoder; 

import java.nio.charset.CharsetEncoder; 

public class ConvertBetweenCharacterSetEncodingsWithCharBuffer { 

    public static void main(String[] args) { 

     //String cadena = "@@@@@@@@@@@@@@@ñâæÃÈÄóöó@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÔÁâãÅÙÃÁÙÄ@ÄÅÂÉã@âæÉãÃÈ@@@@@@@@"; 
     String cadena = "ñâæÃÈÄóöó"; 
     System.out.println(Convert(cadena,"CP1047","ISO-8859-1")); 
     cadena = "1SWCHD363"; 
     System.out.println(Convert(cadena,"ISO-8859-1","CP1047")); 

    } 

    public static String Convert (String strToConvert,String in, String out){ 
     try { 

     Charset charset_in = Charset.forName(out); 
     Charset charset_out = Charset.forName(in); 

     CharsetDecoder decoder = charset_out.newDecoder(); 

     CharsetEncoder encoder = charset_in.newEncoder(); 

     CharBuffer uCharBuffer = CharBuffer.wrap(strToConvert); 

     ByteBuffer bbuf = encoder.encode(uCharBuffer); 

     CharBuffer cbuf = decoder.decode(bbuf); 

     String s = cbuf.toString(); 

     //System.out.println("Original String is: " + s); 
     return s; 

    } catch (CharacterCodingException e) { 

     //System.out.println("Character Coding Error: " + e.getMessage()); 
     return ""; 

    } 


} 

} 
+1

¡Bienvenido a SO! No es necesario explicar su solución, pero considera buenas prácticas, con los agradables efectos secundarios que las personas aprenden a comprender y, por lo tanto, invitan a su respuesta. ;) –

0

Tal vez, like me que no eran estrictamente utilizando una característica de JDBC (Escribir en un coladatos, en mi ejemplo), por lo que el auto-mágica codificación no se aplicaba a que ya que estamos comunicándose a través de múltiples API.

Mi problema era similar al problema de @ scottyab con ciertos caracteres que no mapeaban. En mi caso, el código de ejemplo que estaba haciendo referencia funcionaba perfectamente, pero escribir una cadena xml en una cola de datos resultó en [que se reemplazó por £.

Como desarrollador web que funcione con un motor de base de datos preexistente con décadas de información, yo no simplemente tener la capacidad de los "fallos de configuración" "derecho" como uno de otro comentarista sugiere.

Sin embargo, pude ver qué identificador de conjunto de caracteres codificados probablemente usaría al emitir un comando al 400 para mostrar la información del campo de archivo en un archivo bueno conocido: DSPFFD *LIB*/*FILE*.

Si lo hace, me dio una buena información, incluyendo el conjunto CCSID específica: CCSID Identifier

Después de algún information sought on CCSIDs, me encontré con una página en IBM para EBCDIC los datos fundamentales impresa en la página (ya que tiene la costumbre de desapareciendo):

Versión 11.0.0 Extended Binary coded decimal Intercambio Código (EBCDIC) es un esquema de codificación que se utiliza típicamente en zSeries (z/OS®) y iSeries (I® System).

Y lo más útil:

Algunos CCSID EBCDIC ejemplo son 37, 500 y 1047.

Puesto que ya learned from this question itself que Cp1047 es otro buen juego de caracteres a tratar (Esta vez , el £ se convirtió en una "Y" acentuada), intenté Cp37 para ver que no existía dicho conjunto de caracteres, pero intenté Cp037 y obtuve la codificación correcta.

Parece que la clave es encontrar el que juego de caracteres codificado identificador (CCSID) se utiliza en el sistema, y ​​la garantía de que la instancia jt400 - que de otro modo se trabaja perfeccionando - coincide con el 100% de la codificación establecida en el as400, en mi caso manera antes de mi vida y hace décadas de lógica de negocios.

0

Realizo un código que transforma los tipos de datos fácilmente.

public class Converter{ 

    public static void main(String[] args) { 

     Charset charsetEBCDIC = Charset.forName("CP037"); 
     Charset charsetACSII = Charset.forName("US-ASCII"); 

     String ebcdic = "((((((("; 
     System.out.println("String EBCDIC: " + ebcdic); 
     System.out.println("String converted to ASCII: " + convertTO(ebcdic, charsetEBCDIC, charsetACSII)); 

     String ascII = "MMMMMM"; 
     System.out.println("String ASCII: " + ascII); 
     System.out.println("String converted to EBCDIC: " + convertTO(ascII, charsetACSII, charsetEBCDIC)); 
    } 

    public static String convertTO(String dados, Charset encondingFrom, Charset encondingTo) { 
     return new String(dados.getBytes(encondingFrom), encondingTo); 
    } 
} 
0

Quiero añadir a lo Kwebble y Shawn S han dicho. Puedo usar JTOpen para hacer esto.

Necesitaba escribir en un campo que era 6 0P (6 bytes, nada detrás del decimal, empacado). Eso es un decimal (11,0) para aquellos de ustedes que no asimilan DDM.

AS400PackedDecimal convertedCustId = new AS400PackedDecimal(11, 0); 
    byte[] packedCust = convertedCustId.toBytes((int) custId); 

    String packedCustStr = new String(packedCust, "Cp037"); 

    StringBuilder jcommData = new StringBuilder(); 
    jcommData.append(String.format("%6s", packedCustStr)); 

Sí, he utilizado la biblioteca KWebble mencionado. Al ver DSPPFD como mencionó Shawn S, descubrí que la tabla usaba CCSID 37. Esto funcionó.

Intenté originalmente usar Cp1047, según la sugerencia de Alan Krueger. Pareció funcionar. Desafortunadamente, si mi cliente finaliza con un 5, los datos que se procesaron en el archivo fueron B0 en lugar de 5F. Cambiarlo a Cp037 solucionó eso.

Cuestiones relacionadas