[英]Convert String from ASCII to EBCDIC in Java?
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. Ascii来自Java,Web和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.
我有一个谷歌周围,似乎找不到一个简单的解决方案(也许因为没有一个:()。我希望有一个开源工具或支付已经编写的实用工具。
Like this maybe? 也许这样吗?
Converter.convertToAscii(String textFromAS400)
Converter.convertToEBCDIC(String textFromJava)
Thanks, 谢谢,
Scott 斯科特
Please note that a String in Java holds text in Java's native encoding. 请注意,Java中的String包含Java本机编码的文本。 When holding an ASCII or EBCDIC "string" in memory, prior to encoding as a String, you'll have it in a byte[].
在内存中保存ASCII或EBCDIC“字符串”时,在编码为字符串之前,您将在字节[]中使用它。
ASCII -> Java: new String(bytes, "ASCII") EBCDIC -> Java: new String(bytes, "Cp1047") Java -> ASCII: string.getBytes("ASCII") Java -> EBCDIC: string.getBytes("Cp1047")
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. JTOpen ,IBM的Java工具箱的开源版本具有一组用于访问AS / 400对象的类,包括用于访问本机AS400文本文件的FileReader和FileWriter。 That may be easier to use then writing your own conversion classes.
这可能更容易使用,然后编写自己的转换类。
From the JTOpen homepage: 来自JTOpen主页:
Here are just a few of the many i5/OS and OS/400 resources you can access using JTOpen:
以下是您可以使用JTOpen访问的许多i5 / OS和OS / 400资源中的一小部分:
- Database -- JDBC (SQL) and record-level access (DDM)
数据库 - JDBC(SQL)和记录级访问(DDM)
- Integrated File System
集成文件系统
- Program calls
程序调用
- Commands
命令
- Data queues
数据队列
- Data areas
数据区域
- Print/spool resources
打印/假脱机资源
- Product and PTF information
产品和PTF信息
- Jobs and job logs
工作和工作日志
- Messages, message queues, message files
消息,消息队列,消息文件
- Users and groups
用户和组
- User spaces
用户空间
- System values
系统值
- System status
系统状态
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 "";
}
}
}
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构造函数:
String(byte[] bytes, [int offset, int length,] String enc)
You can create one yoursef with this translation table . 您可以使用此转换表创建一个yoursef。
But here is a site that has a link to a Java example. 但是这里有一个链接到Java示例的站点。
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);
}
}
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 ();
}
}
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. 为EBCDIC字符集编写一个映射应该相当简单,为ASCII字符集编写一个映射,并在每个字符集中返回另一个字符表示。 Then just loop over the string to translate, and look up each character in the map and append it to an output string.
然后循环遍历要翻译的字符串,并查找地图中的每个字符并将其附加到输出字符串。
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. 我不知道是否有公开的转换器,但写一个转换器不应该花费超过一个小时左右。
Perhaps, like me you were not strictly using a JDBC feature (Writing to a Dataqueue, in my instance), so the auto-magical encoding 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. 我的问题类似于@ scottyab的问题,某些字符没有映射。 In my case, the example code I was referencing worked perfectly, but writing an xml string to a dataqueue resulted in [ being replaced with £.
在我的例子中,我引用的示例代码工作得很好,但是将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. 作为一名网络开发人员,使用已有数十年信息的预先存在的数据库后端, 我并没有像其他评论者所说的那样简单地“纠正”“错误配置” 。
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集:
After some information sought on CCSIDs , I ran into a page on IBM for EBCDIC with key information printed on the page (since that has a habit of disappearing): 在收到有关CCSID的一些信息之后,我在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(Systemi®)的编码方案。
And most helpful: 最有帮助的:
Some example EBCDIC CCSIDs are 37, 500, and 1047.
一些示例EBCDIC CCSID是37,500和1047。
Since I already learned from this question itself that Cp1047
is another good character set to try (This time, the £ turned into an accented "Y"), I tried Cp37
to see no such charsset existed, but attempted Cp037
and got the right encoding. 因为我已经从这个问题本身中学到了
Cp1047
是另一个很好的角色设置(这次,£变成了重音的“Y”),我试过Cp37
看不到这样的charsset存在, 但尝试了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 way before my lifetime and decades of business logic ago. 它看起来像关键是找到其编码字符集标识符(CCSID)在你的系统中使用,并确保您的jt400实例-否则正在完善- 100%相匹配对AS400设置编码,在我的情况的方式在我的一生和几十年的商业逻辑之前。
I want to add on to what Kwebble and Shawn S have said. 我想补充一下Kwebble和Shawn S所说的内容。 I can use JTOpen to do this.
我可以使用JTOpen来做到这一点。
I needed to write to a field which was 6 0P (6 bytes, nothing behind the decimal, packed). 我需要写一个6 0P的字段(6个字节,没有小数点后面,打包)。 That's a decimal(11,0) for those of you who don't grok DDM.
对于那些没有理解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. 是的,我使用了KWebble提到的库。 Looking at DSPPFD as Shawn S mentioned, I discovered that the table was using CCSID 37. This worked.
看看Shawn S提到的DSPPFD,我发现该表使用的是CCSID 37.这很有效。
I originally tried using Cp1047, as per Alan Krueger's suggestion. 根据Alan Krueger的建议,我最初尝试使用Cp1047。 It seemed to work.
它似乎工作。 Unfortunately, if my custId ended with a 5, the data rendered into the file was B0 instead of 5F.
不幸的是,如果我的custId以5结尾,则渲染到文件中的数据是B0而不是5F。 Changing it to Cp037 fixed that.
将其更改为Cp037修复了该问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.