In chapter 2, we wrote data to the file at the start, and then read it from the start of the file. We always read the file sequentially. In this chapter, I'll show you how to read the file randomly.
In a standard physical file (one without key fields) you can position by record number using the SETLL and SETGT operations. This makes it possible to access a file "randomly" (or, in other words, you don't have to read through the file sequentially, you can "jump around".)
For a stream file, to read the file randomly, you use the "lseek()" API. However, since stream files are not organized into records by themselves, the lseek() API doesn't seek to a record number. Instead, you give it an "offset" which indicates a number of bytes, rather than records, to jump to.
Here is the C-language prototype for the lseek() API, followed by the corresponding RPG prototype:
off_t lseek(int fildes, off_t offset, int whence)D lseek PR 10I 0 ExtProc('lseek')
D fildes 10I 0 value
D offset 10I 0 value
D whence 10I 0 value
SEEK_SET means that the offset will be from the beginning of the file. An offset of 0 would be the very first byte in the file.
SEEK_CUR means that the offset will be from the current position in the file. For example, if you wanted to re-read the last 5 bytes, you could code SEEK_CUR with an offset of -5
SEEK_END means that the offset will be from the end of the file.
Now that I've told you about the named constants, it'd probably be a good idea to add them to our /copy member, eh?
D SEEK_SET C CONST(0) D SEEK_CUR C CONST(1) D SEEK_END C CONST(2)
Here's a sample of jumping to the end of the file in RPG:
c if lseek(fd: 0: SEEK_END) < 0 c callp EscErrno(errno) c endif
How about jumping to the 157th byte from the start of the file?
c if lseek(fd: 157: SEEK_SET) < 0 c callp EscErrno(errno) c endif
Or, if we're already at byte 157, we could easily seek forward to byte 167, like this:
c if lseek(fd: 10: SEEK_CUR) < 0 c callp EscErrno(errno) c endif