AS/400开发经验点滴(九)SPECIAL文件的使用

一. 什么是SPECIAL文件
我们知道文件是要有存放位置的,是要与某种设备相连的。RPG程序中在定义文件时需要指定文件类别。RPG程序支持文件种类有:

[list:f793ad9784]设备文件 描述 RPG 设备名
打印文件Printer Files 提供打印输出格式描述,以及对打印设备访问 PRINTER
磁带文件Tape Files 提供对存储在磁带设备上的数据文件的访问 SEQ
磁盘文件Diskette Files 提供对存储在磁盘上的数据文件的访问 DISK
显示文件Display Files 提供对显示设备的访问 WORKSTN
通信文件ICF Files 允许程序之间通信 WORKSTN [/list:u:f793ad9784]


此外,RPG程序中还有一种特殊的文件设备类型,定义为SPEICAL。它可以允许指定一种不能被RPG直接操作的的输入/输出设备。对文件的输入/输出操作可以由用户写的程序来完成。用户写的程序名必须在文件定义的F规范中用PGMNAME 关键词来标识。例如:

[code:1:f793ad9784]FTSPF01    IF   E             SPECIAL PGMNAME('TPGMDTQ')  [/code:1:f793ad9784]

虽然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文件记录或接受记录缓冲数据的输入/输出参数:

[list:f793ad9784]参数  类型  长度 说明
Option  Character  1  (O:打开文件C:关闭文件R:读W:写D:删除U:更改F:强制文件结束)
Status  Character  1  (0:正常1:文件结束2:错误)
Error  Packed  5,0  (用户定义错误类型)
Area  Character  Varies  (SPECIAL文件的纪录缓冲)[/list:u:f793ad9784]

除了以上四个隐含参数外,在RPG程序中还可以增加另外的参数传递给用户程序。这可以在SPECIAL文件定义中用PLIST关键词来标识参数列表来实现。然后在RPG程序C规范中用PLIST操作码来定义具体的额外参数。


三. 使用SPECIAL文件的范例


下面通过用SPECIAL文件来操作DTAQ,以提供一个完整范例。该例子用一个RPG程序通过SPECIAL文件调用一个CL程序写一条记录到一个DTAQ中,然后再用另一个RPG程序通过SPECIAL文件调用CL程序从DTAQ中读纪录并显示出来。

1 创建一最大缓冲长度为180的DTAQ

[code:1:f793ad9784]CRTDTAQ DTAQ(TPSFQ) MAXLEN(180) SEQ(*FIFO)[/code:1:f793ad9784]


2  用DDS创建两个文件,用作SPECIAL文件。定义一字段SP0001,长度为180,用来与DTAQ传递和接受数据的记录。

[code:1:f793ad9784]TSPF01

     A          R RSPF01                                                   
     A            SP0001       180          TEXT('QDATA')                  
     A                                      COLHDG(-                       
     A                                      'QDATA')            [/code:1:f793ad9784]
[code:1:f793ad9784]TSPF02

     A          R RSPF02                                              
     A            SP0001       180          TEXT('QDATA')             
     A                                      COLHDG(-                  
     A                                      'QDATA')                             [/code:1:f793ad9784]
3  写一CL程序TPGMDTQ,除了四个隐含参数外,另加指定DTAQ 信息的四个参数。该CL程序指定R和W操作,即读写DTAQ。

[code:1:f793ad9784]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     [/code:1:f793ad9784]                                           

4 一RPG程序使用SPECIAL文件向DTAQ中写一条记录。用PGMNAME标识CL程序TPGMDTQ,用PLIST标识另外的DTAQ参数。


[code:1:f793ad9784]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                                    [/code:1:f793ad9784]       

5  一RPG程序使用SPECIAL文件从DTAQ中读入记录,并显示出来:

[code:1:f793ad9784]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                                                 [/code:1:f793ad9784]


通过上面例子,我们可以看到:通过SPECIAL文件,在RPG程序中我们可以象通常读写磁盘文件一样就可以用DTAQ进行程序间数据交换了。而真正的读写DTAQ操作是在另一CL程序里实现的。

posted @ 2012-01-10 12:40  静海平心  阅读(562)  评论(0编辑  收藏  举报