我有一个java系统通信,作为不同系统(java、大型机等)的网关。该java系统使用例如utf8接收请求并将其转换为目标的编码
问题是,有一个大型机系统正在使用这种晦涩的编码,而我们正在使用的 JDK 不提供这种编码(该字符集是 IBM-924,它是 IBM-1047 https://en.wikibooks的“衍生物” .org/wiki/Character_Encodings/Code_Tables/EBCDIC/EBCDIC_1047)。系统。
据我所知,这个字符集似乎只与 IBM JDK 一起提供,这不是我们使用或想要使用的字符集。
有没有一种方法可以将 IBM JDK 上存在的这一特定字符集合并到例如 openjdk 中?如果没有,除了手动创建字符集之外还有其他选择吗?如果是这样,有没有办法重用 IBM-1047 编码并替换 11 个不匹配的字符?
我尝试使用 IBM JDK 上存在的 charsets.jar 来合并字符集,但它遇到了问题,因为该 jar 依赖于仅存在于 IBM JDK 的 rt.jar 上的类,而且我当然不想替换 rt.jar,因为它可能会导致不必要的副作用。
噢,IBM_924 在整个互联网上几乎不存在。环顾四周,它似乎要么直接是ISO-8859-15 (这是JDK 附带的东西,所以只需使用
Charset.forName("ISO-8859-15")
,或者..就是这个,来自Unicode Consortium的ICU 数据。
这是我从某个随机项目中找到的一些随机映射文件(诚然,来自 unicode 组织的 icu-data 项目;就来源而言,应该具有足够的权威性)。你读它如下:
一行可能包含:
这意味着:
0xA1
如果您在数据流中看到该字节...|1
或多或少意味着:不可往返;这是一个别名。0xA1
之前文件中的相同字节 ( ) 有一个更规范的映射。幸运的是,作为 ISO-8559 变体,它只是“1 个字节 = 1 个字符”,因此,最多只需 256 个不同的字节值即可映射到一个字符。
这意味着编写自己的字符集实现很简单!
这样您就解决了所有问题:将字符集放在您自己的项目中,现在您没有依赖项,也无需依赖内置 IBM-924 的 JVM。
这并不太难。
创建一个名为 的源文件
Ibm924CharsetProvider.java
,扩展自 Java 的CharsetProvider
类。将其复制/粘贴到其中:作为提供者使用
如果您希望例如
new String(bytes, "IBM-924")
工作,并将其列在所有可用字符集的列表中,则需要注册此类。为此,您可以将完全限定的类名(com.foo.yourapp.util.Ibm924CharsetProvider
例如,该字符串)粘贴到一个空的文本文件中。您将此文本文件命名为java.nio.charset.spi.CharsetProvider
。该文件需要位于您的 jar 中,路径为META-INF/services/java.nio.charset.spi.CharsetProvider
. 然后,如果该 jar 位于您的类路径中,那么一切就应该可以正常工作。哦,听起来很复杂
你实际上并不需要这样做——这只是为了确保
"IBM-924"
字符串能够正常工作。您可以按原样使用它,而无需注册提供商。请参阅main
代码片段中的方法,其中我不费心注册它,而是Charset
直接使用该对象。运行它,它会打印:
注意:这种简单化的做法不涉及别名。它们仅与编码相关(如果您需要输出 IBM-924 格式的文本);它们对于解码(读取 IBM-924 格式的文本)没有用。并且仅当您在字符串中使用这些别名时。