在实验性功能探索中,当我尝试使用 Cobol 在大型机系统上加载 UTF-8 的 Unix 文件并将 FD 记录声明为 Unicode 字母数字时,我发现了一些令人震惊的行为。
如果我的记录长度是10(即
10 chunk PIC U(10)
,前10个字符被正确加载。然后跳过30(根据探索显然是长度的3倍),然后它再次读取10个字符。然后接下来的10个字符被读入我的下一张唱片。
我的程序源代码:
IDENTIFICATION DIVISION.
PROGRAM-ID. loadutf8.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT XMLFILE ASSIGN TO "XML".
DATA DIVISION.
FILE SECTION.
FD XMLFILE RECORDING MODE F.
01 chunk PIC U(10).
WORKING-STORAGE SECTION.
01 EOF PIC X.
PROCEDURE DIVISION.
START-PROGRAM.
OPEN INPUT XMLFILE.
PERFORM WITH TEST after UNTIL EOF = 'T'
READ XMLFILE
AT END MOVE 'T' TO EOF
NOT AT END
DISPLAY FUNCTION DISPLAY-of (chunk)
END-READ
END-PERFORM.
CLOSE XMLFILE.
GOBACK.
END PROGRAM loadutf8.
工作卡:
//COBOL EXEC IGYWCLG,LNGPRFX=IGY630
//SYSIN DD DISP=SHR,DSN=COB.SRC(loadutf8)
//GO.XML DD PATH='/u/utf8.xml'
我的 UTF-8 文件:
<?xml ?>
<!-- 0 --><!-- 1 --><!-- 2 --><!-- 3 --><!-- 4 --><!-- 5 --><x>???</x>
观察到的输出:
<?xml ?>
<!-- 3 -->
对我来说,看起来就像根据大小一致地读取块,跳过3次,然后转到下一个块大小,等等..
这可能是什么原因造成的?
是否有最佳实践,如何将 Unix 文件加载到 XML 并使用具有用法 UTF-8 的变量?最好不要任何黑客攻击,只使用“标准”语言功能。
只是出于好奇而问这个问题,任何关于如何解释观察到的结果的想法都值得赞赏。
IBM Enterprise Cobol V6.3 似乎引入了本机 UTF-8 支持。我没有这方面的经验,但是通过阅读手册,我可以解释会发生什么。然而,我不能说这是期望的行为还是错误。
无论如何,在程序员指南(v6.4)中,主题定义UTF-8数据项,可以阅读:
固定字符长度的 UTF-8 数据项。
当 PICTURE 子句包含一个或多个“U”字符,或者单个“U”字符后跟重复因子,并且 PICTURE 子句的 BYTE-LENGTH 短语和指定了 DYNAMIC LENGTH 子句。
还有更多
对于固定字符长度的 UTF-8 数据项, 内存中为该数据项保留的字节数为 4 × n,其中 n 是该项定义中指定的字符数。请注意,由于 UTF-8 编码的长度性质不同,即使将 n 个字符移动到长度为 n 的 UTF-8 数据项后,也不一定需要所有 4 × n 保留字节来保存数据。这取决于数据中每个字符的大小。
在处理 QSAM 文件一章中,可以阅读
我由此得出结论,Cobol 只是建议底层 I/O 例程 (QSAM) 读取多个字节作为“为接收变量保留”,在您的示例中为一次 40 个字节。毕竟,QSAM您还可以使用 QSAM 访问 z/OS UNIX 文件系统中的字节流文件。这些文件是面向二进制字节的顺序文件,没有记录结构。您在 COBOL 程序中编码的记录定义以及您读取和写入的变量的长度决定了传输的数据量。
不支持在读取数据时对其进行解释;它只是读取给定数量的字节而不是字符,并将它们放入输入缓冲区中。 仅当稍后使用该变量时(例如在 DISPLAY 语句中),这些字节才会被解释为 UTF-8 字符。并且,将遵循定义
的 UTF-8 字符数变量长度。我做了一些快速测试并读取了一些文件,其中包含需要 UTF-8 中多个字节的字符,并且显示的数据相应地移动。
尚不确定如何使用 COBOL 成功处理 UTF-8 UNIX 文件。
根据 IBM 的说法,有一个关于使用
https://www.ibm.com/docs/en/cobol-zos/6.4?topic=examples-example-parsing-xml-document-one-segment-time
事件处理程序应相应地对 XML 事件
END-OF-INPUT
作出反应:
Handle-parse-events.
Add 1 to Event-number
Display ' ' Event-number ': ' XML-event '{' XML-text '}'
Evaluate XML-event
When 'END-OF-INPUT'
Read Input-XML
Evaluate Input-XML-status
When 0
Move 1 to XML-code
Display 'Continuing with: ' fdrec
When 10
Display 'At EOF; no more input.'
When other
Display 'Read failed, file status:' Input-XML-status
Goback
End-evaluate
When other
Continue
End-evaluate
.