使用的 JDK 中不存在字符集

fnm*_*mps 6 java mainframe character-encoding charset

我有一个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,因为它可能会导致不必要的副作用。

rzw*_*oot 4

噢,IBM_924 在整个互联网上几乎不存在。环顾四周,它似乎要么直接是ISO-8859-15 (这JDK 附带的东西,所以只需使用Charset.forName("ISO-8859-15"),或者..

\n

就是这个,来自Unicode 联盟ICU 数据

\n

这是我从某个随机项目中找到的一些随机映射文件(诚然,来自 unicode 组织的 icu-data 项目;就来源而言,应该具有足够的权威性)。你读它如下:

\n

一行可能包含:

\n
<UFF5E> \\xA1 |1\n
Run Code Online (Sandbox Code Playgroud)\n

这意味着:

\n
    \n
  • 0xA1如果您在数据流中看到该字节...
  • \n
  • 那么它代表unicode表中的字符0xFF5E。
  • \n
  • |1或多或少意味着:不可往返;这是一个别名。0xA1之前文件中的相同字节 ( ) 有一个更规范的映射。
  • \n
\n

幸运的是,作为 ISO-8559 变体,它只是“1 个字节 = 1 个字符”,因此,最多只需 256 个不同的字节值即可映射到一个字符。

\n

这意味着编写自己的字符集实现很简单!

\n

这样您就解决了所有问题:将字符集放在您自己的项目中,现在您没有依赖项,也无需依赖内置 IBM-924 的 JVM。

\n

这并不太难。

\n

创建一个名为 的源文件Ibm924CharsetProvider.java,从 Java\xe2\x80\x99sCharsetProvider类扩展。将其复制/粘贴到其中:

\n
<UFF5E> \\xA1 |1\n
Run Code Online (Sandbox Code Playgroud)\n

作为提供者使用

\n

如果您希望例如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 位于您的类路径中,那么一切就应该可以正常工作。

\n

哦,听起来很复杂

\n

您实际上并不需要这样做 - 这只是为了确保"IBM-924"字符串能够正常工作。您可以按原样使用它,而无需注册提供商。请参阅main代码片段中的方法,其中我不费心注册它,而是Charset直接使用该对象。

\n

运行它,它会打印:

\n
Hello, World! -> C8 85 93 93 96 6B 40 E6 96 99 93 84 5A\n... -> Hello, World!\nEqual? true\n
Run Code Online (Sandbox Code Playgroud)\n

注意:这种简单化的做法不涉及别名。它们仅与编码相关相关(如果您需要输出 IBM-924 格式的文本);它们对于解码(读取 IBM-924 格式的文本)没有用处。并且仅当您在字符串中使用这些别名时。

\n