我在IFS中有许多具有各种ccsid的文件(0,37,819,1200,1252等),我的任务是编写一个简单的RPGLE[1]程序,该程序将允许用户查看任何这些文件的内容。
我们的系统(V6R1) CCSID (DSPSYSVAL QCCSID)是65535[2],我们的作业的默认CCSID为37,这意味着当我尝试显示CCSID 819 (ASCII)时,例如,我看到垃圾-符号,随机颜色等。
我熟悉通过QtqIconvOpen API将数据从一个CCSID转换为另一个CCSID,所以如果我知道一个文件具有与我们默认的CCSID不同的CCSID,我可以转换它。我几年前写了代码来做这个,它工作得很好。
我的问题是以编程方式找出IFS文件的CCSID。在谷歌搜索了我发现的唯一相关信息后,我在这里找到了来自JamesA的Stackoverflow(如何确定CPYFRMIMPF命令中使用的CCSID ?)谁指出,您可以在QSHELL中执行"ls -S"以获得显示其CCSID和文件名的文件列表。
所以理论上我可以执行ls -S filename
,解析输出以获得CCSID,然后在必要时使用该CCSID执行数据转换。这是一个丑陋的hack,如果可能的话,我更喜欢使用IBM API。
有谁知道这样的API或比解析ls -S filename
中的清单更优雅的hack吗?
[1]我使用C API的open()
, read()
和close()
来进行数据的实际读取。
[2]我知道65535是一个糟糕的选择,但我也无能为力。
看起来Qp0lGetAttr()
"Get Attributes" API将允许您指定一组属性来检索特定文件,包括一个名为QP0L_ATTR_CCSID
的属性。
下面是RPG中使用该API的示例。包含GetAttr调用的示例位于从该页链接的ZIP文件中。
您可以使用集成文件系统api中的stat()函数。
原型定义如下:
D stat PR 10I 0 ExtProc('stat')
D path * Value Options(*string)
D buf Likeds(statDS)
那么你还需要stat数据结构:
D statDS DS Qualified Template
D st_mode 10U 0
D st_ino 10U 0
D st_nlink 5U 0
D st_reserved2 5U 0
D st_uid 10U 0
D st_gid 10U 0
D st_size 10I 0
D st_atime 10I 0
D st_mtime 10I 0
D st_ctime 10I 0
D st_dev 10U 0
D st_blksize 10U 0
D st_allocsize 10U 0
D st_objtype 11A
D st_reserved3 1A
D st_codepage 5U 0
D st_ccsid 5U 0
D st_rdev 10U 0
D st_nlink32 10U 0
D st_rdev64 20U 0
D st_dev64 20U 0
D st_reserved1 36A
D st_ino_gen_id 10U 0
使用起来很简单
D fileStats DS Likeds(statDS)
/free
if stat('/path/to/file': fileStats) < 0;
// error handling
endif;
// ccsid now in fileStats.st_ccsid
/end-free
为什么不使用DSPF呢?IBM的实用程序做得很好;不知道还需要什么