【问题标题】:Convert String from ASCII to EBCDIC in Java?在Java中将字符串从ASCII转换为EBCDIC?
【发布时间】:2008-12-15 14:55:22
【问题描述】:

我需要编写一个“简单”的工具来从 ASCII 转换为 EBCDIC?

Ascii 来自 Java、Web 和 AS400。我有一个谷歌,似乎找不到一个简单的解决方案(也许因为没有一个:()。我希望有一个开源工具或为已经编写的工具付费。

也许像这样?

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

谢谢,

斯科特

【问题讨论】:

  • 您是否必须处理重新定义和打包记录,或者这是直接翻译?

标签: java ascii ibm-midrange ebcdic


【解决方案1】:

请注意,Java 中的字符串以 Java 的本机编码保存文本。在内存中保存 ASCII 或 EBCDIC“字符串”时,在编码为字符串之前,您将在 byte[] 中拥有它。

ASCII -> Java:新字符串(字节,“ASCII”) EBCDIC -> Java:新字符串(字节,“Cp1047”) Java -> ASCII:string.getBytes("ASCII") Java -> EBCDIC: string.getBytes("Cp1047")

【讨论】:

【解决方案2】:

JTOpen,IBM 的 Java 工具箱的开源版本有一组用于访问 AS/400 对象的类,包括用于访问本机 AS400 文本文件的 FileReader 和 FileWriter。这可能比编写自己的转换类更容易使用。

来自 JTOpen 主页:

这里只是您可以使用 JTOpen 访问的众多 i5/OS 和 OS/400 资源中的一小部分:

  • 数据库 -- JDBC (SQL) 和记录级访问 (DDM)
  • 集成文件系统
  • 程序调用
  • 命令
  • 数据队列
  • 数据区
  • 打印/假脱机资源
  • 产品和 PTF 信息
  • 作业和作业日志
  • 消息、消息队列、消息文件
  • 用户和组
  • 用户空间
  • 系统值
  • 系统状态

【讨论】:

  • 我们正在使用 JTopen 工具箱,它正在做一些转换/映射,只是它似乎错误地映射了 £、$、[ 和 ^
  • 听起来您的 AS/400 的母语配置不正确。如果设置正确,jt400.jar 将不需要任何其他调整。
  • 是的,转换应该基本上是自动发生的。如果不是,则说明设置不正确。
【解决方案3】:

您应该使用 Java 字符集 Cp1047 (Java 5) 或 Cp500 (JDK 1.3+)。

使用字符串构造函数:String(byte[] bytes, [int offset, int length,] String enc)

【讨论】:

  • 你忘记了 Cp037(我们有那个)。您应该建议该人验证正在使用的字符集。
【解决方案4】:
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!解释您的解决方案不是必需的,但考虑了良好的做法,具有人们学会理解并因此支持您的答案的良好副作用。 ;)
【解决方案5】:

你可以用这个translation table自己创建一个。

here 是一个包含指向 Java 示例的链接的站点。

【讨论】:

  • 第二个链接失效了。你知道它去哪儿了吗?你能把例子贴在这里吗?
  • @BilltheLizard web.archive.org/web/20080112153232/https://reply42.com/…。也许我应该编辑答案,但是......
  • 如果原始文件不再在线,则可以使用 Web 存档链接。我会继续编辑答案。此外,您本可以等到 11 月 8 日在我发表评论 10 周年时回复。 ;p
【解决方案6】:

也许,like me 您没有严格使用 JDBC 功能(在我的例子中,写入数据队列),所以 auto-magical 编码不适用于您,因为我们是通过多个 API 进行通信。

我的问题类似于@scottyab 的问题,某些字符没有映射。就我而言,我引用的示例代码运行良好,但是将 xml 字符串写入数据队列导致 [ 被替换为 £。

作为一名使用已有数十年信息的数据库后端的 Web 开发人员,我并没有像其他评论者所说的那样简单地“纠正”“错误配置” .

但是,通过向 400 发出命令以显示已知良好文件的文件字段信息,我能够看到我可能使用的编码字符集标识符:DSPFFD *LIB*/*FILE*

这样做给了我很好的信息,包括特定的 CCSID 集:

information sought on CCSIDs之后,我跑到IBM的一个页面EBCDIC,页面上印有关键信息(因为有消失的习惯):

11.0.0 版扩展二进制编码十进制交换码 (EBCDIC) 是一种编码方案,通常用于 zSeries (z/OS®) 和 iSeries (System i®)。

最有帮助的:

一些示例 EBCDIC CCSID 是 37、500 和 1047。

由于我已经 learned from this question itself 认为 Cp1047 是另一个值得尝试的好字符集(这一次,£ 变成了带重音的“Y”),我尝试了 Cp37 以查看不存在这样的字符集,但尝试了Cp037 并得到了正确的编码。

看起来关键是找出您的系统中使用了哪个编码字符集标识符 (CCSID),并确保您的 jt400 实例(否则正在完善)与as400 上的编码设置,在我的情况下 方式 在我有生之年和几十年前的业务逻辑之前。

【讨论】:

    【解决方案7】:

    我编写了一个可以轻松转换数据类型的代码。

    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);
        }
    }
    

    【讨论】:

      【解决方案8】:

      我想补充一下 Kwebble 和 Shawn S 所说的话。我可以使用 JTOpen 来做到这一点。

      我需要写入一个 6 0P 的字段(6 个字节,小数点后面没有,打包)。对于那些不了解 DDM 的人来说,这是一个小数 (11,0)。

          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 提到的库。查看 Shawn S 提到的 DSPPFD,我发现该表使用的是 CCSID 37。这很有效。

      按照 Alan Krueger 的建议,我最初尝试使用 Cp1047。它似乎奏效了。不幸的是,如果我的 custId 以 5 结尾,则呈现到文件中的数据是 B0 而不是 5F。将其更改为 Cp037 即可解决此问题。

      【讨论】:

        【解决方案9】:

        为 EBCDIC 字符集和 ASCII 字符集编写一个映射应该相当简单,并且在每个映射中都返回另一个的字符表示。然后只需遍历要翻译的字符串,并在地图中查找每个字符并将其附加到输出字符串。

        我不知道有没有公开的转换器,但是写一个应该不会超过一个小时左右。

        【讨论】:

          【解决方案10】:

          这是我一直在使用的。

          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 ();
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多