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

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

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

可能这样吗?

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

谢谢,

斯科特

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

来自JTOpen主页:

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

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

请注意,Java中的String包含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”)
 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 ""; } } } 

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

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

您可以使用此转换表创建一个yoursef。

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

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

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

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

我不知道是否有任何转换器是公开的,但写一个转换器不应该花费超过一个小时左右。

这就是我一直在使用的。

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

也许, 和我一样,你并没有严格使用JDBCfunction(在我的实例中写入数据队列),所以自动魔法编码不适用于你,因为我们通过多个API进行通信。

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

作为一名网络开发人员,使用预先存在的数据库后端和数十年的信息, 我不像其他评论者所建议的那样简单地“纠正”“错误配置”

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

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

在收到有关CCSID的一些信息后,我在IBM页面上搜索了EBCDIC的页面,页面上印有关键信息(因为它有消失的习惯):

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

最有帮助的:

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

因为我已经从这个问题本身中学到了Cp1047是另一个好的角色设置(这次,£变成了重音的“Y”),我试过Cp37看不到这样的charsset存在, 但尝试了Cp037并得到了正确的编码。

看起来关键是找到在您的系统中使用哪个编码字符集标识符(CCSID) ,并确保您的jt400实例 – 否则正在完善 – 与as400上的编码集匹配100%,就我而言在我的一生和几十年的商业逻辑之前。

我想补充一下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修复了该问题。