PreviousMiscellaneous Topics Callable Sort APINext"

Chapter 12: Byte-stream File Handling

The standard COBOL READ and WRITE statements handle formatted data (records) during file input/output operations. Alternatively, you can handle a file as a byte-stream, that is, you access data in the file by specifying the starting position and the length of the block that you want to read or write. This chapter describes the COBOL system library routines which enable you to access any file as a byte-stream.

12.1 Overview

You can use byte-stream I/O to handle files of a format not supported by this system, to handle files of your own format, to write your own file handler or to process line sequential files as a simple stream of text.


Caution: You should not use byte-stream I/O to access files of a format supported by COBOL syntax or the Callable File Handler, as this can easily lead to file corruption.


A sample program byteio.cbl, which can be found using Infomgr, illustrates the use of these routines. You can review this program as you are reading this section. Note especially the section in the code that determines the size of the file and the checks that are performed to ensure that the program does not read beyond the end of the file.

12.2 Byte-stream Routines

The byte-stream routines are:

CBL_CREATE_FILE Opens the file for output. If the file already exists, this routine overwrites it.
CBL_OPEN_FILE Opens a file for byte-stream I/O.
CBL_READ_FILE Reads a specified number of bytes from the file, or as much of it as fits into the buffer.
CBL_WRITE_FILE Writes the specified number of bytes to a file.
CBL_CLOSE_FILE Releases the file handle for use by other files. If you do not explicitly close the file, the run-time system closes the file for you when your program completes.
CBL_FLUSH_FILE Causes all data in memory buffers to be written to disk.

The following library routines complement the byte-stream I/O routines:

CBL_GET_RECORD_LOCK Acquires a record lock on a file.
CBL_FREE_RECORD_LOCK Releases a record lock on a file.
CBL_TEST_RECORD_LOCK Tests for a record lock on a file.

Example

The following sample code creates a file:

     call "CBL_CREATE_FILE"
         using filename, access-mode, deny-mode,
         device, file-handle 

Byte-stream I/O deals with a stream of bytes; there is no concept of an end-of-file mark and so you must be careful to ensure that you do not read beyond the end of the file.

You must not use byte-stream I/O and COBOL I/O on the same file. For example, if you open a file using CBL_OPEN_FILE, you must not read from that file using a standard COBOL READ statement.

12.2.1 Introduction to Byte-stream Routines

For all these routines, if the routine is successful the RETURN-CODE register is set to zero. If the routine fails, the RETURN-CODE register contains a file status value indicating the failure. This file status is always the standard ANSI'74 file status value. If no ANSI'74 file status is defined for the error, an extended file status is returned (9/nnn where nnn is the RTS error number).

You should, therefore, use RETURN-CODE and not a RETURNING clause. If RETURN-CODE is non-zero after calling a byte-stream routine, you must process it as a file status, for example:

 01 file-status      pic xx comp-x. 
 01 redefines file-status. 
     03 fs-byte-1  pic x. 
     03 fs-byte-2  pic x comp-x. 
   . . . 
     call "CBL_xxx_FILE" using parameters 
     if return-code not = 0 
        move return-code to file-status 
           . . .

At this point fs-byte-1 contains "9" and fs-byte-2 contains the run-time system error number.

12.2.2 Descriptions of the Byte-stream Routines


CBL_CLOSE_FILE

Closes a file opened for byte-stream operations.

Syntax:
call "CBL_CLOSE_FILE" using      file-handle
Parameters:

file-handle         pic x(4).

On Entry:
file-handle The file handle returned when the file was opened.
On Exit:

None

Comments:

Any byte-stream file open when a STOP RUN is executed is automatically closed.

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


CBL_CREATE_FILE

Creates a new file for byte-stream operations.

Syntax:
call "CBL_CREATE_FILE" using      filename 
                                  access-mode 
                                  deny-mode 
                                  device 
                                  file-handle
Parameters:

filename            pic x(n).
access-mode         pic x comp-x.
deny-mode           pic x comp-x.
device              pic x comp-x.
file-handle         pic x(4).

On Entry:
filename Space- or null-terminated filename of the file to be opened.
access-mode Must be 0.
deny-mode Defines deny mode:
0 Deny both read and write (exclusive)
1 Deny write
2 Deny read
3 Deny neither read nor write
device Reserved for future use (must be 0).
On Exit:
file-handle Returns a file handle for a successful open.
Comments:

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


CBL_FLUSH_FILE

Ensures all file buffers for a file are written to disk. This includes both run-time system buffers and operating system buffers.

Syntax:
call "CBL_FLUSH_FILE" using file-handle
Parameters:

file-handle         pic x(4)

On Entry:
file-handle The file handle returned when the file was opened (by CBL_OPEN_FILE).
On Exit:
RETURN-CODE Indicates whether the routine was successful:
0 Success
-1 Buffers might not have been flushed
Other Two-byte file status code indicating the error.
Comments:

On some operating systems it is not possible to flush the file buffers. In this case, the appropriate status-code is returned.

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


CBL_FREE_RECORD_LOCK

Releases a record lock on a file.

Syntax:
call "CBL_FREE_RECORD_LOCK" using file-handle 
                                  record-offset 
                                  record-length 
                                  reserved 

Parameters:

file-handle         pic x(4).
record-offset       pic x(4)comp-x.
record-length       pic x(4)comp-x.
reserved            pic x(2)comp-x.

On Entry:
file-handle The file handle returned by a successful CBL_OPEN_FILE or CBL_CREATE_FILE.
record-offset The offset, within the file, of the first byte to unlock.
record-length The number of bytes to unlock.
reserved Must be zero.
On Exit:
RETURN-CODE Indicates whether the routine was successful:
0 Success
9/nnn File status indicating error condition.
Comments:

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


CBL_GET_RECORD_LOCK

Acquires a record lock on a file.

Syntax:
call "CBL_GET_RECORD_LOCK" using  file-handle 
                                  record-offset 
                                  record-length 
                                  reserved 

Parameters:

file-handle         pic x(4).
record-offset       pic x(4)comp-x.
record-length       pic x(4)comp-x.
reserved            pic x(2)comp-x.

On Entry:
file-handle The file handle returned by a successful CBL_OPEN_FILE or CBL_CREATE_FILE.
record-offset The offset, within the file, of the first byte to lock.
record-length The number of bytes to lock.
reserved Must be zero.
On Exit:
RETURN-CODE Indicates whether the routine was successful:
0 Success
1 Lock already owned by run unit.
9/nnn File status indicating error condition.
Comments:

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


CBL_OPEN_FILE

Opens an existing file for byte-stream operations.

Syntax:
call "CBL_OPEN_FILE" using      filename 
                                access-mode 
                                deny-mode 
                                device 
                                file-handle
Parameters:

filename            pic x(n).
access-mode         pic x comp-x.
deny-mode           pic x comp-x.
device              pic x comp-x.
file-handle         pic x(4).

On Entry:
filename Space- or null-terminated filename of the file to be opened.
access-mode Defines access mode:
1 Read only
2 Write only (deny-mode must be 0)
3 Read/write
deny-mode Defines deny mode:
0 Deny both read and write (exclusive)
1 Deny write
2 Deny read
3 Deny neither read nor write
device Reserved for future use (must be 0).
On Exit:
file-handle Returns a file handle for a successful open.
Comments:

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


CBL_READ_FILE

Reads bytes from a file.

Syntax:
call "CBL_READ_FILE" using      file-handle 
                                file-offset 
                                byte-count 
                                flags 
                                buffer
Parameters:

file-handle         pic x(4).
file-offset         pic x(8) comp-x.
byte-count          pic x(4) comp-x.
flags               pic x comp-x.
buffer              pic x(n).

On Entry:
file-handle The file handle returned when the file was opened.
file-offset The offset in the file at which to read. This field is currently limited to a maximum value of x"00FFFFFFFF".
byte-count The number of bytes to read. This field is currently limited to a maximum value of x"00FFFF".
flags This parameter can take the following values:

0 Standard read
128 Return the current file size in file-offset
On Exit:
file-offset Contains the current file size on return if flags is set to 128 on entry.
buffer The buffer into which the bytes are read. It is your responsibility to ensure that the buffer is large enough to hold the number of bytes to be read.

buffer is allowed to cross a 64K segment boundary.

Comments:

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.

When using this routine to read a file that is contained in a Micro Focus library file (.lbr), the end-of-file status is not returned. To ensure you only read the file you want, obtain the size of the file first (set flags to 128), and only read up to that size.


CBL_TEST_RECORD_LOCK

Tests for an existing record lock on a file.

Syntax:
call "CBL_TEST_RECORD_LOCK" using file-handle 
                                  record-offset 
                                  record-length 
                                  reserved 

Parameters:

file-handle         pic x(4).
record-offset       pic x(4)comp-x.
record-length       pic x(4)comp-x.
reserved            pic x(2)comp-x.

On Entry:
file-handle The file handle returned by a successful CBL_OPEN_FILE or CBL_CREATE_FILE.
record-offset The offset, within the file, of the first byte to test.
record-length The number of bytes to test.
reserved Must be zero.
On Exit:
RETURN-CODE Indicates whether the routine was successful:
0 Success
1 Lock already owned by run unit.
9/nnn File status indicating error condition.

CBL_WRITE_FILE

Writes bytes to a file.

Syntax:
call "CBL_WRITE_FILE" using      file-handle 
                                 file-offset 
                                 byte-count 
                                 flags 
                                 buffer
Parameters:

file-handle         pic x(4).
file-offset         pic x(8) comp-x.
byte-count          pic x(4) comp-x.
flags               pic x comp-x.
buffer              pic x(n).

On Entry:
file-handle The file handle returned when the file was opened.
file-offset The offset in the file at which to write. This field is currently limited to a maximum value of x"00FFFFFFFF".
byte-count The number of bytes to write. This field is currently limited to a maximum value of x"00FFFF".
flags This parameter can take the following value:
0 Standard write
buffer The buffer from which the bytes are written. It is your responsibility to ensure that the buffer is large enough to hold the number of bytes to be written.

buffer is allowed to cross a 64K segment boundary.

On Exit:

None

Comments:

The success of the call can be checked by examining RETURN-CODE. See Introduction to Byte-stream Routines for more details.


12.3 Sample Program

The following example program contains routines to open and close files to be processed as byte-stream files, one for input, one for output and to read and write individual bytes using buffering.

$SET ANS85
*===============================================================*

 working-storage section
 78 fals value 0
 78 tru  value 1.

*---------------------------------------------------------------*
* WS for byte-stream handling

 78 in-buff-len      value 4096.

 01 in-buff          pic x(in-buff-len).

 01 infilename      pic x(64).
 01 infile-handle    pic x(4).
 01 infile-offset    pic x(8) comp-x value 0.
 01 infile-len       pic x(8) comp-x.

 01 in-buff-ptr      pic x(2) comp-x.
 01 in-buff-end      pic x(4) comp-x value in-buff-len.

 78 out-buff-len     value 4096.

 01 out-buff         pic x(out-buff-len).

 01 outfilename     pic x(64).
 01 outfile-handle   pic x(4).
 01 outfile-offset   pic x(8) comp-x value 0.
 01 outfile-len      pic x(8) comp-x.

 01 out-buff-ptr     pic x(2) comp-x.
 01 out-buff-end     pic x(4) comp-x value in-buff-len.

 01 bs-misc.
     03 eof-flag         pic x comp-x value fals.
         88 eof              value tru.
     03 last-block-flag  pic x comp-x value fals.
         88 last-block       value tru.
     03 display-put-flag pic x comp-x value fals.
         88 display-put      value tru false fals.

     03 next-byte.
         05 next-byte-n  pic x comp-x.
     03 save-byte        pic x.
 01 k-0              pic x comp-x value 0.
 01 k-1              pic x comp-x value 1.
 01 k-2              pic x comp-x value 2.
 01 k-128            pic x comp-x value 128.

*---------------------------------------------------------------*
*===============================================================*
 procedure division.
 aa-control section.
     perform ca-initial.
     perform cc-process.
     perform ce-final
     .

 aa-990-exit.
     exit program
     stop run
     .

 ca-initial section.
     move "inbyte.dat" to infilename
     move "outbyte.dat" to outfilename
     perform open-in-file
     perform open-out-file
     .

 cc-process section.

* Examine each byte, and process as required when the appropriate
* byte is found (as identified by the when clause)

     perform get-byte
     perform until eof
         evaluate next-byte
          when .......


          when other
             perform put-byte
             perform get-byte
         end-evaluate
     end-perform
     .
 ce-final section.
     perform close-in-file
     perform close-out-file
     .

*---------------------------------------------------------------*
* Input byte-stream file code

 open-in-file section.
     call "CBL_OPEN_FILE" using infilename
                                k-1
                                k-0
                                k-0
                                infile-handle
     if return-code not = 0
         display "Open failed: "
                 infilename
         stop run
     end-if

* Find length of input file.
     call "CBL_READ_FILE" using infile-handle
                                infile-offset
                                in-buff-end
                                k-128
                                in-buff
     move infile-offset to infile-len
     move 0 to infile-offset
     move in-buff-len to in-buff-ptr
     add 1 to in-buff-ptr
     move fals to last-block-flag
     move fals to eof-flag
     .

 get-byte section.
     if in-buff-ptr = in-buff-end
         if last-block
             set eof to true
             move x"ff" to next-byte
         else
             perform get-next-block
             if in-buff-end = 0
                 set eof to true
                 move x"ff" to next-byte
             end-if
         end-if
     end-if
     if not eof
         move in-buff (in-buff-ptr : 1) to next-byte
         add 1 to in-buff-ptr
*        display next-byte
*            with no advancing
     end-if
     .

 get-previous-byte section.
     if in-buff-ptr = 2
         subtract 2 from in-buff-ptr
     else
         perform get-previous-block
     end-if
     perform get-byte
     .

 get-next-block section.
     call "CBL_READ_FILE" using infile-handle
                                infile-offset
                                in-buff-end
                                k-0
                                in-buff
     end-call
     move 1 to in-buff-ptr
     add in-buff-end to infile-offset
     if infile-offset = infile-len
         subtract infile-len from infile-offset
         subtract infile-offset from in-buff-end
         move tru to last-block-flag
     end-if
     .

 get-previous-block section.
     if last-block
         move fals to last-block-flag
         move in-buff-len to in-buff-end
         add infile-len to infile-offset
     end-if
     subtract in-buff-end from infile-offset
     call "CBL_READ_FILE" using infile-handle
                         infile-offset
                         in-buff-end
                         k-0
                         in-buff
     end-call
     move in-buff-len to in-buff-ptr
     .
 close-in-file section.
     call "CBL_CLOSE_FILE" using infile-handle
     .

*=================================================================
* Output byte-stream file code

 open-out-file section.
     call "CBL_CREATE_FILE" using outfilename
                                k-2
                                k-0
                                k-0
                                outfile-handle
     if return-code not = 0
         display "Open failed: "
                 outfilename
         stop run
     end-if
     move 1 to out-buff-ptr
     .

 put-byte section.
     if display-put
         display next-byte
             with no advancing
     end-if
     move next-byte to out-buff (out-buff-ptr:1)
     add 1 to out-buff-ptr
     if out-buff-ptr = out-buff-len
         perform write-block
         move 1 to out-buff-ptr
     end-if
     .

 write-block section.
     call "CBL_WRITE_FILE" using outfile-handle
                                 outfile-offset
                                 out-buff-end
                                 k-0
                                 out-buff
     end-call
     add out-buff-end to outfile-offset
     .
 close-out-file section.
     if out-buff-ptr = 1
         move out-buff-ptr to out-buff-end
         subtract 1 from out-buff-end
         perform write-block
     end-if
     call "CBL_CLOSE_FILE" using outfile-handle
     .




Copyright © 2000 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousMiscellaneous Topics Callable Sort APINext"