从 Cobol 中的 PATH 以 UTF-8 格式读取文件

Read File from PATH in Cobol as UTF-8

提问人:MJG 提问时间:11/29/2022 更新时间:12/1/2022 访问量:270

问:

在一次实验性功能探索中,当我尝试使用 Cobol 在大型机系统上加载一个 UTF-8 的 Unix 文件并将 FD 记录声明为 Unicode 字母数字时,我发现了一些惊人的行为。

如果我的记录长度为 10(即 ,则正确加载了前 10 个字符。然后跳过 30 个字符(根据探索,显然是长度的 3 倍),然后再次读取 10 个字符。然后,接下来的 10 个字符被读入我的下一条记录。10 chunk PIC U(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 的变量?最好没有任何黑客攻击,只使用“标准”语言功能。

只是出于好奇而问这个问题,任何关于如何解释观察到的结果的想法都是值得赞赏的。

XML UNIX UTF-8 COBOL 大型机

评论

0赞 Simon Sobisch 11/29/2022
你使用哪个似乎对你的情况是错误的 - 丢弃它时行为会改变吗?RECORDING MODE IS F
0赞 MJG 11/30/2022
由于该模式是默认@SimonSobisch(固定),我还尝试了其他允许的模式(V、U),但结果总是有相同的输出。F

答:

2赞 phunsoft 12/1/2022 #1

IBM Enterprise Cobol V6.3 似乎引入了原生 UTF-8 支持。我没有这方面的经验,但通过阅读手册,我可以解释会发生什么。但是,我不能说这是期望的行为还是错误。

无论如何,在程序员指南 (v6.4) 主题定义 UTF-8 数据项中,可以阅读:

修复了字符长度为 UTF-8 的数据项。

当 PICTURE 子句包含一个或多个“U”字符,或单个“U”字符后跟重复因子,并且既未指定 PICTURE 子句的 BYTE-LENGTH 短语,也未指定 DYNAMIC LENGTH 子句时,将定义这种类型的 UTF-8 数据项。

并进一步

对于固定字符长度的 UTF-8 数据项,内存中为数据项保留的字节数为 4 × n,其中 n 是项定义中指定的字符数。请注意,由于 UTF-8 编码的长度性质各不相同,即使在将 n 个字符移动到长度为 n 的 UTF-8 数据项后,也不一定需要所有 4 × n 个保留字节来保存数据。这取决于数据中每个字符的大小。

处理 QSAM 文件的章节中,可以阅读

您还可以使用 QSAM 访问 z/OS UNIX 文件系统中的字节流文件。这些文件是二进制面向字节的顺序文件,没有记录结构。您在 COBOL 程序中编码的记录定义以及您读入和写入的变量的长度决定了传输的数据量。

我由此得出结论,Cobol 只是建议底层 I/O 例程 (QSAM) 读取为接收变量保留的许多字节,在您的示例中,接收变量一次为 40 个字节。毕竟,QSAM不支持在读取数据时解释数据;它只是读取给定数量的字节,而不是字符,并将它们放在输入缓冲区中。

仅当以后使用该变量时,例如在 DISPLAY 语句中,字节才会被解释为 UTF-8 字符。并且,然后尊重定义的 UTF-8 字符数中的变量长度。

我做了一些快速测试并读取了一些文件,其中包含在 UTF-8 中需要多个字节的字符,并且显示的数据相应地移动。

还不确定如何使用 COBOL 成功处理 UTF-8 UNIX 文件。

评论

1赞 MJG 12/1/2022
感谢您@phunsoft的全面回答。是的,我完全同意,因为所有字符的大小都是 1 位,因此观察到的偏移量非常有意义。也许使用(或创建)服务/库将文件加载到变量中可能是一个考虑因素,因为此时 UTF-8 读取可能更可行。
1赞 Simon Sobisch 12/1/2022
@MJG,您可以侥幸读取数据,并重新定义 as 并从那里使用它(当然,当末尾有多个字节时会产生问题)。否则,将阅读移出图书馆听起来是最合理的。PIC XPIC UCALL
0赞 MJG 12/1/2022
@SimonSobisch重新定义有助于解决当前问题,谢谢。是的,必须正确处理末尾的多字节情况,并且在 COBOL 中对此进行编码似乎是可行的。
0赞 phunsoft 12/1/2022
来自语言参考:当 UTF-8 数据包含组合字符序列时,程序员负责确保对 UTF-8 字符的操作不会无意中分离形成图形字符的多个编码单元分组。您必须注意参考修改,并避免在移动过程中截断。COBOL 运行时系统不检查构成图形字符的编码单元组之间的拆分。多么三心二意的 UTF-8 支持!