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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/368603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:54:11  来源:igfitidea点击:

Convert String from ASCII to EBCDIC in Java?

javaasciiibm-midrangeebcdic

提问by scottyab

I need to write a 'simple' util to convert from ASCII to EBCDIC?

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

The Ascii is coming from Java, Web and going to an AS400. I've had a google around, can't seem to find a easy solution (maybe coz there isn't one :( ). I was hoping for an opensource util or paid for util that has already been written.

Ascii 来自 Java、Web 并转为 AS400。我有一个 google,似乎无法找到一个简单的解决方案(也许因为没有一个 :( )。我希望有一个开源 util 或为已经编写的 util 付费。

Like this maybe?

也许像这样?

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

Thanks,

谢谢,

Scott

斯科特

采纳答案by Kwebble

JTOpen, IBM's open source version of their Java toolbox has a collection of classes to access AS/400 objects, including a FileReader and FileWriter to access native AS400 text files. That may be easier to use then writing your own conversion classes.

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

From the JTOpen homepage:

从 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 访问的众多 i5/OS 和 OS/400 资源中的一小部分:

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

回答by Elie

It should be fairly simple to write a map for the EBCDIC character set, and one for the ASCII character set, and in each return the character representation of the other. Then just loop over the string to translate, and look up each character in the map and append it to an output string.

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

I don't know if there are any converter's publicly available, but it shouldn't take more than an hour or so to write one.

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

回答by Toon Krijthe

You can create one yoursef with this translation table.

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

But hereis a site that has a link to a Java example.

这里有一个站点,其中包含指向 Java 示例的链接。

回答by JeeBee

You should use either the Java character set Cp1047 (Java 5) or Cp500 (JDK 1.3+).

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

Use the String constructor: String(byte[] bytes, [int offset, int length,] String enc)

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

回答by Alan Krueger

Please note that a String in Java holds text in Java's native encoding. When holding an ASCII or EBCDIC "string" in memory, prior to encoding as a String, you'll have it in a byte[].

请注意,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")

回答by dmolony

This is what I've been using.

这是我一直在用的。

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

回答by leo_con

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 = "@@@@@@@@@@@@@@@?a??è?ó?ó@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?áa??ù?áù?@???é?@a?é??è@@@@@@@@";
        String cadena = "?a??è?ó?ó";
        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 "";

    }


}

}

回答by Shawn

Perhaps, like meyou were not strictly using a JDBC feature (Writing to a Dataqueue, in my instance), so the auto-magicalencoding didn't apply to you since we're communicating through multiple APIs.

也许,像我一样,您没有严格使用 JDBC 功能(在我的例子中是写入数据队列),因此自动魔法编码不适用于您,因为我们通过多个 API 进行通信。

My issue was similar to @scottyab's issue with certain characters not mapping. In my case, the example code I was referencing worked perfectly, but writing an xml string to a dataqueue resulted in [ being replaced with £.

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

As a web developer working with a pre-existing database backend with decades of information, I didn't simply have the ability to "right" the "mis-configuration"as one other commenter suggests.

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

However, I was able to see which Coded Character Set Identifier the i was likely using by issuing a command to the 400 to display file field information on a known good file: DSPFFD *LIB*/*FILE*.

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

Doing so gave me good information, including the specific CCSID set: CCSID Identifier

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

After some information sought on CCSIDs, I ran into a page on IBM for EBCDICwith key information printed on the page (since that has a habit of disappearing):

CCSIDs 上寻找一些信息后,我在 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?).

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

And most helpful:

最有帮助的:

Some example EBCDIC CCSIDs are 37, 500, and 1047.

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

Since I already learned from this question itselfthat Cp1047is another good character set to try (This time, the £ turned into an accented "Y"), I tried Cp37to see no such charsset existed, but attempted Cp037and got the right encoding.

由于我已经从这个问题本身了解到这Cp1047是另一个值得尝试的好字符集(这一次,£ 变成了带重音的“Y”),我试图Cp37看到不存在这样的字符集,但尝试Cp037并获得了正确的编码。

It looks like the key is finding which Coded Character Set Identifier (CCSID)is used in your system, and ensuring that your jt400 instance - which otherwise is working perfecting - matches up 100% to the encoding set on the as400, in my case waybefore my lifetime and decades of business logic ago.

它看起来像关键是找到其编码字符集标识符(CCSID)在你的系统中使用,并确保您的jt400实例-否则正在完善-比赛高达100%的编码集的AS400,在我的情况的方式在我的有生之年和几十年前的业务逻辑之前。

回答by Gustavo Vieira de Souza

I make a code that transforms data types easily.

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

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

回答by Meower68

I want to add on to what Kwebble and Shawn S have said. I can use JTOpen to do this.

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

I needed to write to a field which was 6 0P (6 bytes, nothing behind the decimal, packed). That's a decimal(11,0) for those of you who don't grok DDM.

我需要写入一个 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));

Yes, I used the library KWebble mentioned. Looking at DSPPFD as Shawn S mentioned, I discovered that the table was using CCSID 37. This worked.

是的,我使用了 KWebble 提到的库。看着 Shawn S 提到的 DSPPFD,我发现该表使用的是 CCSID 37。这是有效的。

I originally tried using Cp1047, as per Alan Krueger's suggestion. It seemed to work. Unfortunately, if my custId ended with a 5, the data rendered into the file was B0 instead of 5F. Changing it to Cp037 fixed that.

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