Преобразовать строку из ASCII в EBCDIC в Java? - PullRequest
16 голосов
/ 15 декабря 2008

Мне нужно написать «простой» утилиты для преобразования из ASCII в EBCDIC?

Ascii идет с Java, Web и собирается на AS400. У меня был гугл, кажется, я не могу найти простое решение (может потому что его нет :(). Я надеялся на утилиту с открытым исходным кодом или заплатил за утилиту, которая уже была написана.

Как это может быть?

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

Спасибо,

Scott

Ответы [ 10 ]

28 голосов
/ 16 декабря 2008

Обратите внимание, что строка в Java содержит текст в собственной кодировке Java. Когда в памяти содержится «строка» ASCII или EBCDIC, перед кодированием в виде строки вы получите ее в байте [].

ASCII -> Java:   new String(bytes, "ASCII")
EBCDIC -> Java:  new String(bytes, "Cp1047")
Java -> ASCII:   string.getBytes("ASCII")
Java -> EBCDIC:  string.getBytes("Cp1047")
10 голосов
/ 15 декабря 2008

JTOpen , версия IBM с открытым исходным кодом их набора инструментов Java имеет набор классов для доступа к объектам AS / 400, включая FileReader и FileWriter для доступа к собственным текстовым файлам AS400. Это может быть проще в использовании, чем написание собственных классов преобразования.

С домашней страницы JTOpen:

Вот лишь некоторые из множества ресурсов i5 / OS и OS / 400, к которым вы можете получить доступ с помощью JTOpen:

  • База данных - JDBC (SQL) и доступ на уровне записей (DDM)
  • Интегрированная файловая система
  • Программные вызовы
  • Команда
  • Очереди данных
  • Области данных
  • Ресурсы печати / буферизации
  • Информация о продукте и PTF
  • Задания и журналы заданий
  • Сообщения, очереди сообщений, файлы сообщений
  • Пользователи и группы
  • Пользовательские пространства
  • Системные значения
  • Состояние системы
3 голосов
/ 02 апреля 2015
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 "";

    }


}

}
2 голосов
/ 15 декабря 2008

Вы должны использовать либо набор символов Java Cp1047 (Java 5), ​​либо Cp500 (JDK 1.3 +).

Используйте конструктор String: String(byte[] bytes, [int offset, int length,] String enc)

1 голос
/ 02 февраля 2017

Я создаю код, который легко преобразует типы данных.

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);
    }
}
1 голос
/ 15 декабря 2008

Вы можете создать свою личность с помощью этой таблицы перевода .

Но здесь - это сайт, на котором есть ссылка на пример Java.

0 голосов
/ 24 августа 2017

Я хочу добавить к тому, что сказали Квеббл и Шон С. Я могу использовать JTOpen, чтобы сделать это.

Мне нужно было записать в поле, которое было 6 0P (6 байт, ничего после десятичного числа, упаковано). Это десятичное число (11,0) для тех из вас, кто не любит 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));

Да, я использовал упомянутую библиотеку KWebble. Глядя на DSPPFD, как упоминал Шон С., я обнаружил, что таблица использует CCSID 37. Это сработало.

Изначально я пытался использовать Cp1047 в соответствии с предложением Алана Крюгера. Казалось, работает. К сожалению, если мой custId заканчивался 5, данные, отображаемые в файл, были B0 вместо 5F. Изменение на Cp037 исправило это.

0 голосов
/ 24 января 2017

Возможно, , как и я Вы не использовали строго функцию JDBC (в моем случае запись в Dataqueue), поэтому автоматическое магическое кодирование к вам не относится поскольку мы общаемся через несколько API.

Моя проблема была похожа на проблему @ scottyab с определенными символами, которые не отображались. В моем случае пример кода, на который я ссылался, работал отлично, но запись строки XML в очередь данных привела к [замене на £.

Как веб-разработчик, работающий с уже существующей базой данных базы данных с десятилетиями информации, У меня не было просто возможности "исправить" "неправильную конфигурацию" , как предлагает другой комментатор.

Однако я смог увидеть, какой идентификатор набора кодированных символов я, вероятно, использовал, введя команду 400 для отображения информации о поле файла в известном исправном файле: DSPFFD *LIB*/*FILE*.

Это дало мне хорошую информацию, включая конкретный набор CCSID: CCSID Identifier

После некоторой информации, запрашиваемой по CCSID , я наткнулся на страницу IBM для EBCDIC с ключевой информацией, напечатанной на странице (поскольку она имеет привычку исчезать):

Версия 11.0.0 Расширенный двоичный код десятичного кода обмена (EBCDIC) схема кодирования, которая обычно используется в zSeries (z / OS) и iSeries (System i®).

И самое полезное:

Некоторыми примерами CCSID EBCDIC являются 37, 500 и 1047.

Поскольку я уже узнал из самого этого вопроса , что Cp1047 - еще один хороший набор символов, который нужно попробовать (На этот раз символ £ превратился в акцентированное "Y"), я попытался Cp37, чтобы увидеть такого набора символов не было, , но попытался Cp037 и получил правильную кодировку.

Похоже, ключ находит, какой Идентификатор набора кодов (CCSID) используется в вашей системе, и гарантирует, что ваш экземпляр jt400 - который в противном случае работает идеально - соответствует 100% кодированию установить на as400, в моем случае way до моей жизни и десятилетий бизнес-логики назад.

0 голосов
/ 02 января 2015

Это то, что я использовал.

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 ();
  }
}
0 голосов
/ 15 декабря 2008

Должно быть довольно просто написать карту для набора символов EBCDIC, и одну для набора символов ASCII, и в каждом возвращать представление символов другого. Затем просто переберите строку для перевода, найдите каждый символ на карте и добавьте его к выходной строке.

Я не знаю, есть ли какой-либо конвертер, общедоступный, но на его написание уйдет не более часа.

...