我需要读取配置单元数据库表并以 EBCDIC 编码的文本格式写入该信息,因为这将用作大型机进程的输入。我们正在使用 cp037 编码。 为此,我将配置单元表读入 df,然后调用自定义 udf 将数值转换为 COMP3 格式(用于在大型机中存储数值),然后使用大型机 EBCDIC 字符集的 cp037 对其进行解码。问题是在写入文本文件或显示值时添加了一些额外的垃圾字符。
首先,我确保自定义 udf 工作正常。为此,我使用 cp037 编码回自定义 udf 的输出,下面的输出即将到来,这是完美的和预期的。这里的 newcol1 是 field1 的 MF comp3 等价物,newcol2 是 field2 的 MF COMP3 等价物。
root
|-- field1: long (nullable = true)
|-- newcol1: binary (nullable = true)
|-- field2: long (nullable = true)
|-- newcol2: binary (nullable = true)
+---------------+----------------------+---------------------------+----------------+
|field1 |newcol1 |field2 |newcol2 |
+---------------+----------------------+---------------------------+----------------+
|2023097000 |[00 02 02 30 97 00 0C]|320264 |[00 03 20 26 4F]|
|2023097000 |[00 02 02 30 97 00 0C]|343012 |[00 03 43 01 2F]|
|2023100000 |[00 02 02 31 00 00 0C]|343012 |[00 03 43 01 2F]|
|2023100000 |[00 02 02 31 00 00 0C]|320264 |[00 03 20 26 4F]|
+---------------+----------------------+---------------------------+----------------+
但是当我在解码垃圾字符后尝试编写/显示相同内容时
after doing decoding
root
|-- field1: long (nullable = true)
|-- newcol11: string (nullable = true)
|-- field2: long (nullable = true)
|-- newcol21: string (nullable = true)
+---------------+--------+---------------------------+--------+
|field1 |newcol11|field2 |newcol21|
+---------------+--------+---------------------------+--------+
|2023097000 |^@^B^B~Pp^@^L |320264 |^@^C~@^W| |
|2023097000 |^@^B^B~Pp^@^L |343012 |^@^C?^A^G |
|2023100000 |^@^B^B~Q^@^@^L |343012 |^@^C?^A^G |
|2023100000 |^@^B^B~Q^@^@^L |320264 |^@^C~@^W| |
+---------------+--------+---------------------------+--------+
Mainframe 文件如下所示(请注意,我已经将 HEX 设置为 ON 以显示实际的字节)
********************************
-------------------------------
2023097000...Ì.p..320264..Ì..|
FFFFFFFFFF00073900FFFFFF00722444
20230970000228070C32026403806F00
-------------------------------
如果您注意到字节 X'78' 是添加的垃圾字符。
我正在使用的 pyspark 文件写入命令是 df.coalesce(1).write.format('text').option("encoding","cp037").mode('overwrite').save('/some_location/test/comp3_outputdata/')
似乎在写入文本格式时不支持编码选项。
根据以下链接,pyspark 在调用文本方法时似乎不支持编码。
我负担不起任何其他格式,因为我的输出文件将直接由大型机进程获取。 有人可以帮我解决这个问题吗??
COMP-3 是 COBOL 中使用的术语,指的是 IBM Z 硬件上的压缩十进制格式。其他格式包括二进制的 COMP。把它想象成一个 int32.
在十进制格式中,有几个十进制指令可以处理各种算术运算的数字。目前尚不清楚您想在问题中做什么,但由于您参考了 COMP-3,因此有一个合理的假设,即您希望 COBOL 程序使用 CP-037 代码页将您的数字数据处理为压缩十进制和文本信息。旁注,CP-037 通常用于欧洲系统,而 CP-1047 用于北美系统。
压缩十进制的二进制结构与代码页无关。
在您的情况下,您需要根据数据类型处理每一列。在你的情况下,你会根据你的例子得到这样的东西:
field1
- strnewcol1
- comp-3field2
- strnewcol2
- comp-3不是使用 CP 037 编码(仅对 field1 和 field2 有效)转换整个记录,您需要使用转换来转换 field1 和 field2。对于 newcol1 和 newcol2,您希望它们保持不变。将它们复制到新的输出记录或保持不变。因为它们是二进制编码,所以会产生像你在 x'78' 中看到的那样时髦的翻译。
我在字段级别使用了 cp037 编码,正如@hogstorm 所强调的那样。事实证明,即将出现的额外字符是由于发送文件时的 SFT 问题……我的代码一直运行良好。来自 pyspark 的最终文件,包括普通字符串和编码的 comp3 字段,是 utf8 格式,但在将它们发送到 MF 时,我们没有以二进制模式发送它们,这就是大型机文件包含垃圾值的原因。 一旦在 sft 传输中将模式设置为二进制,问题就解决了..