- 论坛徽章:
- 0
|
AS/400开发经验点滴(九)-- SPECIAL文件的使用
一. 什么是SPECIAL文件
我们知道文件是要有存放位置的,是要与某种设备相连的。RPG程序中在定义文件时需要指定文件类别。RPG程序支持文件种类有:
设备文件 描述 RPG 设备名
打印文件Printer Files 提供打印输出格式描述,以及对打印设备访问 PRINTER
磁带文件Tape Files 提供对存储在磁带设备上的数据文件的访问 SEQ
磁盘文件Diskette Files 提供对存储在磁盘上的数据文件的访问 DISK
显示文件Display Files 提供对显示设备的访问 WORKSTN
通信文件ICF Files 允许程序之间通信 WORKSTN
此外,RPG程序中还有一种特殊的文件设备类型,定义为SPEICAL。它可以允许指定一种不能被RPG直接操作的的输入/输出设备。对文件的输入/输出操作可以由用户写的程序来完成。用户写的程序名必须在文件定义的F规范中用PGMNAME 关键词来标识。例如:
- FTSPF01 IF E SPECIAL PGMNAME('TPGMDTQ')
复制代码
虽然SPECIAL文件原目的是提供一种让RPG程序从不能直接 操作的设备上可以进行访问的方法。但SPECIAL文件的使用可以不仅限于此,实际上通过SPECIAL文件,可以做很多事。它可以通过指定用户写的程序来允许RPG程序完成一些RPG程序不可能完成的任务,或者通过规范输入/输出方法来简化程序结构等等。
二. SPECIAL文件有关参数定义
RPG程序本身是通过RPG操作码打开(OPEN),读(READ),写(WRITE),关闭(CLOSE) SPECIAL文件,SPEICAL文件再把这些动作传递给PGNNAME标识的用户程序,再由用户程序来完成对实际设备文件的打开,读,写,关闭等操作。实际上对SPECIAL文件,RPG程序自动创建四个参数:
操作码(option ),
返回状态(status),
错误码(error),
记录域(area)
这四个参数可以被RPG编译器和用户程序访问,但不能被包含SPECIAL文件的RPG程序本身访问。对用户程序而言,其中option是输入参数,status和error是返回参数,area则是用来传递SPECIAL文件记录或接受记录缓冲数据的输入/输出参数:
参数 类型 长度 说明
Option Character 1 (O:打开文件C:关闭文件R:读W:写D:删除U:更改F:强制文件结束)
Status Character 1 (0:正常1:文件结束2:错误)
Error Packed 5,0 (用户定义错误类型)
Area Character Varies (SPECIAL文件的纪录缓冲)
除了以上四个隐含参数外,在RPG程序中还可以增加另外的参数传递给用户程序。这可以在SPECIAL文件定义中用PLIST关键词来标识参数列表来实现。然后在RPG程序C规范中用PLIST操作码来定义具体的额外参数。
三. 使用SPECIAL文件的范例
下面通过用SPECIAL文件来操作DTAQ,以提供一个完整范例。该例子用一个RPG程序通过SPECIAL文件调用一个CL程序写一条记录到一个DTAQ中,然后再用另一个RPG程序通过SPECIAL文件调用CL程序从DTAQ中读纪录并显示出来。
1 创建一最大缓冲长度为180的DTAQ
- CRTDTAQ DTAQ(TPSFQ) MAXLEN(180) SEQ(*FIFO)
复制代码
2 用DDS创建两个文件,用作SPECIAL文件。定义一字段SP0001,长度为180,用来与DTAQ传递和接受数据的记录。
- TSPF01
- A R RSPF01
- A SP0001 180 TEXT('QDATA')
- A COLHDG(-
- A 'QDATA')
复制代码- TSPF02
- A R RSPF02
- A SP0001 180 TEXT('QDATA')
- A COLHDG(-
- A 'QDATA')
复制代码
3 写一CL程序TPGMDTQ,除了四个隐含参数外,另加指定DTAQ 信息的四个参数。该CL程序指定R和W操作,即读写DTAQ。
- TPGMDTQ
- /** **/
- /** Description - This program is used to send and receive **/
- /** from dataq. **/
-
- PGM PARM(&OPTION &STATUS &ERROR &AREA &DATAQ +
- &LIB &WAIT &LEN)
- DCL VAR(&OPTION) TYPE(*CHAR) LEN(1)
- DCL VAR(&STATUS) TYPE(*CHAR) LEN(1)
- DCL VAR(&ERROR) TYPE(*DEC) LEN(5 0)
- DCL VAR(&AREA) TYPE(*CHAR) LEN(180)
- DCL VAR(&DATAQ) TYPE(*CHAR) LEN(10)
- DCL VAR(&LIB) TYPE(*CHAR) LEN(10)
- DCL VAR(&LEN) TYPE(*DEC) LEN(5 0) VALUE(180)
- DCL VAR(&WAIT) TYPE(*DEC) LEN(5 0)
-
- IF COND(&OPTION *EQ 'R') THEN(DO)
- CALL PGM(QRCVDTAQ) PARM(&DATAQ &LIB &LEN +
- &AREA &WAIT)
- IF COND(&LEN *LE 0) THEN(CHGVAR VAR(&AREA) +
- VALUE(' '))
- ENDDO
-
- IF COND(&OPTION *EQ 'W') THEN(DO)
- CALL PGM(QSNDDTAQ) PARM(&DATAQ &LIB &LEN &AREA)
- ENDDO
-
- IF COND(&OPTION *EQ 'O') THEN(GOTO CMDLBL(ENDALL))
-
- RETURN
- ENDALL: ENDPGM
复制代码
4 一RPG程序使用SPECIAL文件向DTAQ中写一条记录。用PGMNAME标识CL程序TPGMDTQ,用PLIST标识另外的DTAQ参数。
- TSPFPGMW
- F* Write to TSPFQ queue.
- FTSPF02 O E SPECIAL PGMNAME('TPGMDTQ')
- F PLIST(DQOUT)
- F*****************************************************************
- C DQOUT PLIST
- C PARM DATAQ 10
- C PARM LIB 10
- C PARM WAIT 5 0
- C PARM OUTLEN 5 0
- C
- C Z-ADD 180 OUTLEN
- C MOVEL 'TSPFQ ' DATAQ 10
- C MOVEL 'CNDEVLGB' LIB 10
- C Z-SUB 1 WAIT
- C* SEND
- C EVAL SP0001 = 'This is a tesk!'
- C WRITE RSPF02
- C RETURN
- C MOVE '1' *INLR
复制代码
5 一RPG程序使用SPECIAL文件从DTAQ中读入记录,并显示出来:
- TSPFPGMR
- F* Read from TSPFQ queue.
- FTSPF01 IF E SPECIAL PGMNAME('TPGMDTQ')
- F PLIST(DQIN)
- F*****************************************************************
- C DQIN PLIST
- C PARM DATAQ 10
- C PARM LIB 10
- C PARM WAIT 5 0
- C PARM OUTLEN 5 0
- C
- C Z-ADD 180 OUTLEN
- C MOVEL 'TSPFQ ' DATAQ 10
- C MOVEL 'MYTSTLIB' LIB 10
- C Z-SUB 1 WAIT
- C* Receive
- C READ RSPF01 40
- C MOVEL SP0001 DTXT 40
- C DTXT DSPLY
- C RETURN
复制代码
通过上面例子,我们可以看到:通过SPECIAL文件,在RPG程序中我们可以象通常读写磁盘文件一样就可以用DTAQ进行程序间数据交换了。而真正的读写DTAQ操作是在另一CL程序里实现的。
BLOG LIOU
2005.06.13
参考:
Special Files Can Do It All
http://www.itjungle.com/fhg/fhg041305-story01.html |
|