Мне нужно написать «простую» утилиту для преобразования из ASCII в EBCDIC?
Ascii идет от Java, Web и переходит на AS400. У меня был Google, похоже, не могу найти простого решения (возможно, потому что его нет :(). Я надеялся на утилиту с открытым исходным кодом или заплатил за утилиту, которая уже была написана.
Может быть, вот так?
Converter.convertToAscii(String textFromAS400)
Converter.convertToEBCDIC(String textFromJava)
Спасибо,
Скотт




Должно быть довольно просто написать карту для набора символов EBCDIC и одну для набора символов ASCII, и в каждом из них возвращать символьное представление другого. Затем просто переберите строку для перевода, найдите каждый символ на карте и добавьте его в строку вывода.
Я не знаю, есть ли в открытом доступе какой-либо конвертер, но на его написание не уйдет больше часа.
Вы можете создать его самостоятельно с помощью этого таблица перевода.
Но здесь - это сайт, на котором есть ссылка на пример Java.
Вторая ссылка мертва. Вы знаете, куда это делось? Вы можете разместить здесь пример?
Вы должны использовать набор символов Java Cp1047 (Java 5) или Cp500 (JDK 1.3+).
Используйте конструктор String: String(byte[] bytes, [int offset, int length,] String enc)
Вы забыли Cp037 (он у нас есть). Вы должны предложить человеку проверить, какой набор символов используется.
JTOpen, версия IBM с открытым исходным кодом своего набора инструментов Java, имеет набор классов для доступа к объектам AS / 400, включая FileReader и FileWriter для доступа к собственным текстовым файлам AS400. Это может быть проще в использовании, чем писать собственные классы преобразования.
С домашней страницы JTOpen:
Here are just a few of the many i5/OS and OS/400 resources you can access using JTOpen:
- Database -- JDBC (SQL) and record-level access (DDM)
- Integrated File System
- Program calls
- Commands
- Data queues
- Data areas
- Print/spool resources
- Product and PTF information
- Jobs and job logs
- Messages, message queues, message files
- Users and groups
- User spaces
- System values
- System status
Мы используем панель инструментов JTopen, и она выполняет некоторую часть преобразования / сопоставления, просто кажется, что неправильно сопоставляет £, $, [и ^
Похоже, ваша AS / 400 неправильно настроена в отношении родного языка. Если он настроен правильно, jt400.jar не потребует никаких дополнительных настроек.
Да, преобразование должно происходить в основном автоматически. Если это не так, что-то не так.
Обратите внимание, что String в 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")
Существует множество кодовых таблиц EBCDIC. Исправлять вручную очень утомительно.
Наборы символов Java, начинающиеся с "CP", относятся к IBM CCSID. Некоторую документацию по ним можно найти на www-03.ibm.com/systems/i/software/globalization/ccsid_list.h tml, а www-03.ibm.com/systems/i/software/globalization/codepages.ht мл CP1047, по-видимому, относится к 01047, «Latin 1 / Open Systems».
@AlanKrueger на сегодняшний день эти ссылки мертвы. Это действительно плохо.
@some_coder - новая ссылка www-01.ibm.com/software/globalization/cp/cp_cpgid.html
Это то, что я использовал.
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 ();
}
}
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 "";
}
}
}
Добро пожаловать в SO! Объяснять свое решение не требуется, но с учетом хорошей практики, с хорошими побочными эффектами, которые люди учатся понимать и, следовательно, голосовать за ваш ответ. ;)
Возможно, как я, вы не использовали строго функцию JDBC (в моем случае запись в очередь данных), поэтому кодировка авто-магический к вам не применялась, поскольку мы общаемся через несколько API.
Моя проблема была похожа на проблему @scottyab, когда некоторые символы не отображались. В моем случае пример кода, на который я ссылался, работал отлично, но запись строки xml в очередь данных привела к замене [на £.
Как веб-разработчик, работающий с уже существующей базой данных с десятилетиями информации, У меня просто не было возможности «исправить» «неправильную конфигурацию»., как предлагает один другой комментатор.
Однако я смог увидеть, какой идентификатор набора кодированных символов, вероятно, использовал i, выполнив команду на 400 для отображения информации о поле файла в заведомо исправном файле: DSPFFD *LIB*/*FILE*.
Это дало мне хорошую информацию, включая конкретный набор CCSID:

После некоторого запрашиваемая информация о CCSID я наткнулся на страницу IBM для EBCDIC с ключевой информацией, напечатанной на странице (поскольку она имеет привычку исчезать):
Version 11.0.0 Extended Binary Coded Decimal Interchange Code (EBCDIC) is an encoding scheme that is typically used on zSeries (z/OS®) and iSeries (System i®).
И самое полезное:
Some example EBCDIC CCSIDs are 37, 500, and 1047.
Поскольку я уже сказал узнал из самого этого вопроса, что Cp1047 - еще один хороший набор символов, который стоит попробовать (на этот раз символ £ превратился в букву «Y» с акцентом), я попробовал Cp37, чтобы увидеть, что такого набора символов не существует, но попробовал Cp037 и получил правильную кодировку.
Похоже, ключ заключается в том, чтобы найти, какой Идентификатор кодированного набора символов (CCSID) используется в вашей системе, и убедиться, что ваш экземпляр jt400 - который в противном случае работает безупречно - соответствует на 100% кодировке, установленной на as400, в моем случае путь до моей жизни и десятилетий бизнес-логика назад.
Я делаю код, который легко преобразует типы данных.
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);
}
}
Я хочу добавить к тому, что сказали Квеббл и Шон С. Для этого я могу использовать 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 исправило это.
Вам приходится иметь дело с переопределением и упакованными записями, или это прямая трансляция?