«... преобразовано в EBCDIC ...» может быть частью проблемы.
Если процесс преобразования мэйнфрейма не «знает» о макете записи, с которым он работает (т.е. какие столбцы содержатдвоичные, упакованные и / или символьные данные), это может что-то испортить, потому что процесс отображения зависит от формата.
Вы указали, что данные COMP-3 в порядке, я готов поспорить, что либо«преобразовано в EBCDIC» ничего не делает, или выполняет какое-то преобразование ASCII в COMP-3 для всех ваших данных - таким образом, запутывая данные не в COMP-3.
Как только вы доберетесь домэйнфрейм, это то, что вы должны увидеть:
COMP-3 - каждый байт содержит 2 цифры, кроме последней (справа, младший, младший).Младший значащий байт содержит только 1 десятичную цифру в старших 4 битах и поле знака в младших 4 битах.Каждая десятичная цифра записывается в шестнадцатеричном формате (например, 5 = B'0101 ')
Зональная десятичная дробь (нормальные числа) - каждый байт содержит 1 десятичную цифру.Старшие четыре бита должны всегда содержать HEX F, за исключением, возможно, самого младшего старшего байта, где старшие 4 бита могут содержать знак, а младшие 4 бита - цифру.4-разрядная цифра записывается в шестнадцатеричном формате (например, 5 = B'0101 ')
Вам необходимо увидеть, как выглядят преобразованные данные без сжатия на мэйнфрейме.Попросите кого-нибудь «ПРОСМОТРЕТЬ» ваш файл на мэйнфрейме с помощью «HEX ON», чтобы вы могли видеть, каково фактическое содержимое HEX вашего файла.Оттуда вы сможете выяснить, через какие обручи и петли вам нужно перейти, чтобы сделать эту работу.
Вот несколько ссылок, которые могут вам помочь:
Обновление: Если мэйнфреймРебята могут видеть правильные цифры при просмотре с помощью "HEX ON", тогда есть две возможные проблемы:
- Цифра хранится в неправильном клеве.Цифра должна быть видна в нижних 4 битах.Если он находится в старших 4 битах, то это определенно является проблемой.
- Недискретный полубайт (старшие 4 бита) не содержит HEX 'F' или действительного значения знака.Цифры без знака всегда содержат HEX 'F' в старших 4 битах байта.Если число подписано (например, PIC S9 (4) - или что-то в этом роде), старшие 4 бита самой младшей значащей цифры (последней) должны содержать HEX 'C' или 'D'.
Вот скриншот того, как должен выглядеть BROWSE с «HEX ON»:
File Edit Edit_Settings Menu Utilities Compilers Test Help
VIEW USERID.TEST.DATA - 01.99 Columns 00001 00072
Command ===> Scroll ===> CSR
****** ***************************** Top of Data ******************************
000001 0123456789
FFFFFFFFFF44444444444444444444444444444444444444444444444444444444444444
012345678900000000000000000000000000000000000000000000000000000000000000
------------------------------------------------------------------------------
000002 |¬?"±°
012345678944444444444444444444444444444444444444444444444444444444444444
FFFFFFFFF000000000000000000000000000000000000000000000000000000000000000
------------------------------------------------------------------------------
000003 àíÃÏhr
012345678944444444444444444444444444444444444444444444444444444444444444
012345678900000000000000000000000000000000000000000000000000000000000000
------------------------------------------------------------------------------
Строки, начинающиеся с «000001», «000002» и «000003», показываютпростой текст.две строки под каждой из них показывают шестнадцатеричное представление символа над ним.Первая строка HEX показывает 4 старших бита, вторая строка - 4 младших бита.
- В строке 1 содержится число «0123456789», за которым следуют пробелы (HEX 40).
- Строка 2 показывает мусор, потому что верхний и нижний кусочки перевернуты.Точный глупый символ - просто вопрос выбора кодовой страницы, поэтому не увлекайтесь тем, что видите.
- Строка 3 показывает схожий мусор, потому что верхний и нижний полубайты содержат цифры.
Строка '000001' - это то, что вы должны увидеть для зонированных десятичных чисел без знака на мэйнфрейме IBM, используя EBCDIC (однобайтовый набор символов).
UPDATE 2
Вы добавили HEX-дисплей к своему вопросу 6 июня.Я думаю, возможно, было несколько проблем с форматированием.Если это то, что вы пытались отобразить, вам может помочь следующее обсуждение:
..........A..
33333333326004444
210003166750C0000
Вы заметили, что это отображение двух «цифр»:
- 210003166 в зонированном десятичном числе
- 000000002765000 в COMP-3
Это то, что мэйнфрейм IBM ожидает:
210003166 :Á : <-- Display character
FFFFFFFFF00002600 <-- Upper 4 bits of each byte
2100031660000750C <-- Lower 4 bits of each byte
Обратите внимание на различия между тем, что выиметь и выше:
- старшие 4 бита зонированных десятичных данных на вашем дисплее содержатHEX '3', они должны содержать HEx 'F'. Нижние 4 бита содержат
ожидаемая цифра. Исправьте эти 4 старших бита
и тебе должно быть хорошо идти. Кстати ... мне кажется, что "конверсия" вас
пытались Zoned Decimal не имеет никакого влияния. Битовые паттерны, которые вы имеете для
каждая цифра в зонированной десятичной дроби соответствует цифрам в наборе символов ASCII.
- В поле COMP-3 вы указали, что начальные нули могут быть обрезаны.
Извините, но они либо являются частью числа, либо нет! Мой дисплей выше
включает в себя ведущие нули. Ваш дисплей имеет усеченные начальные нули, а затем дополнен
завершающие байты с пробелами (HEX 40). Это не сработает! Поля COMP-3 определены
с фиксированным числом цифр и все цифры должны быть представлены - это означает, что ведущий
нули требуются для заполнения старших цифр каждого числа.
Исправление Zoned Decimal должно быть довольно простым ... Исправление COMP-3, вероятно, просто
дело в том, чтобы не удалять начальные нули (в противном случае это выглядит довольно хорошо).
ОБНОВЛЕНИЕ 3 ...
Как вы переворачиваете 4 старших бита? У меня сложилось впечатление, что вы можете делать свое преобразование с помощью Java-программы.
Я, к сожалению, программист на COBOL, но я попробую (не
смех) ...
Исходя из того, что я видел здесь, все, что вам нужно сделать, это взять каждый ASCII
оцифруйте и переверните старшие 4 бита в HEX F, и результат будет эквивалентен
неотмеченная зонированная десятичная цифра EBCDIC. Попробуйте что-то вроде ...
public static byte AsciiToZonedDecimal(byte b) {
//flip upper 4 bits to Hex F...
return (byte)(b | 0xF0)
};
Примените вышеизложенное к каждой цифре ASCII, и результат должен быть без знака EBCDIC
Зональное десятичное число.
ОБНОВЛЕНИЕ 4 ...
На этом этапе ответы Джеймса Андерсона должны направить вас на правильный путь.
Джеймс указал вам name.benjaminjwhite.zdecimal и
похоже, в нем есть все классы Java, необходимые для преобразования ваших данных.
Метод StringToZone
должна быть в состоянии преобразовать строку IDENTIFIER, которую вы возвращаете из Oracle, в байтовый массив, который вы затем добавляете в
выходной файл.
Я не очень знаком с Java, но я считаю, что строки Java хранятся внутри как символы Юникода, длина которых составляет 16 бит. EBCDIC
длина символов, которые вы пытаетесь создать, составляет всего 8 бит. Учитывая это, вам может быть лучше записать в выходной файл, используя байтовые массивы (в отличие от строк).
Просто догадка от не Java-программиста.
Метод toZoned
в вашем вопросе, по-видимому, касается только первого
и последние символы строки. Часть проблемы в том, что каждый персонаж
необходимо преобразовать - 4 старших бита каждого байта, кроме, возможно, последнего, должны быть исправлены, чтобы содержать шестнадцатеричный код F. Нижние 4 бита содержат одну цифру.
Кстати ... Вы можете подобрать источник для этого служебного класса Java по адресу: http://www.benjaminjwhite.name/zdecimal