在Java中将字符串从ASCII转换为EBCDIC?

在Java中将字符串从ASCII转换为EBCDIC?,java,ascii,ibm-midrange,ebcdic,Java,Ascii,Ibm Midrange,Ebcdic,我需要编写一个“简单”的util来将ASCII转换为EBCDIC Ascii来自Java、Web和AS400。我有一个谷歌,似乎找不到一个简单的解决方案(可能是因为没有:()。我希望有一个开源的util或付费的util,已经编写好了) 也许像这样 Converter.convertToAscii(String textFromAS400) Converter.convertToEBCDIC(String textFromJava) 谢谢 Scott为EBCDIC字符集编写一个映射,为ASCII

我需要编写一个“简单”的util来将ASCII转换为EBCDIC

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

也许像这样

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


Scott

为EBCDIC字符集编写一个映射,为ASCII字符集编写一个映射,并在每个映射中返回另一个的字符表示,应该相当简单。然后只需在字符串上循环进行翻译,并在映射中查找每个字符并将其附加到输出字符串中


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

你可以用这个创建一个转换器


但是是一个有Java示例链接的站点。

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

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

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

从JTOpen主页:

以下是您可以使用JTOpen访问的许多i5/OS和OS/400资源中的一些:

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

请注意,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") ASCII->Java:新字符串(字节,“ASCII”) EBCDIC->Java:新字符串(字节,“Cp1047”) Java->ASCII:string.getBytes(“ASCII”) Java->EBCDIC:string.getBytes(“Cp1047”)
这就是我一直在用的

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 ();
  }
}
public static final int[]ebc2asc=new int[256];
公共静态最终整数[]asc2ebc=新整数[256];
静止的
{
字节[]值=新字节[256];
对于(int i=0;i<256;i++)
值[i]=(字节)i;
尝试
{
字符串s=新字符串(值为“CP1047”);
char[]chars=s.toCharArray();
对于(int i=0;i<256;i++)
{
int val=字符[i];
ebc2asc[i]=val;
asc2ebc[val]=i;
}
}
捕获(不支持的编码异常e)
{
e、 printStackTrace();
}
}
也许,您没有严格使用JDBC功能(在我的例子中,写入数据队列),因此自动魔法编码不适用于您,因为我们通过多个API进行通信

我的问题类似于@scottyab的问题,某些字符没有映射。在我的例子中,我引用的示例代码工作得很好,但将xml字符串写入数据队列导致[被替换为]

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

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

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

经过一段时间后,我在IBM for上遇到了一个页面,页面上打印了关键信息(因为这有消失的习惯):

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

最有帮助的是:

一些示例EBCDIC CCSID为37、500和1047

由于我已经知道
Cp1047
是另一个需要尝试的好字符集(这次,%变成了重音“Y”),我尝试
Cp37
查看不存在这样的字符集,但是尝试
Cp037
并得到了正确的编码。


密钥似乎正在查找哪个编码字符集标识符(CCSID)在您的系统中使用,并确保您的jt400实例(否则正在完善工作)与as400上的编码集100%匹配,在我有生之年和几十年前的业务逻辑中都是如此。

我制作了一个可以轻松转换数据类型的代码

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

我想补充一下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提到的DSPPFD,我发现该表使用的是CCSID 37。这很有效


根据Alan Krueger的建议,我最初尝试使用Cp1047。它似乎有效。不幸的是,如果我的custId以5结尾,则呈现到文件中的数据是B0而不是5F。将其更改为Cp037修复了这一问题。

您必须处理重定义和打包的记录,还是这是直接转换?我们使用的是JTopen工具箱它正在进行一些转换/映射,只是它似乎映射不正确,$,[和^听起来您的AS/400的母语配置不正确。如果设置正确,jt400.jar将不需要任何其他调整。是的,转换基本上应该自动进行。如果没有,则说明设置不正确。存在问题
    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));