RexxFile: File I/O routines ( vs 4.00, January 2003)
The class RexxFile contains a complete object oriented implementation of the character/line oriented I/O routines of classic REXX, namely stream, linein, lineout, lines, chars, charin and charout, as well as a couple of utility routines useful for File I/O in general. The old function oriented calling sequence is provided for convenience as well.
The Rexxfile package may be used in any NetRexx/Java program as well. In this case, you should add the statements
Import Rexx2Nrx.Rexx2RT.RexxFile
Class class-name[parameters] USES RexxFile
to your program.
Note, that the Rexx2Nrx translator replaces the original, function oriented calls by object oriented method invokations whenever possible, and also substitutes constant parameters given by the proper properties of the RexxFile object.
Note, that in particular, variations of the various stream-commands are directly replaced to use the proper properties/methods of the RexxFile object whenever possible,
Public Properties of a RexxFile object:
For each RexxFile-Object, the following public properties are maintained:
| FileNo = Int 0 | unique RexxFile File-Number |
| FileFile = File Null | the associated FILE object |
| FileName = Rexx '' | the actual given file name, blank is console |
| FileFullName = Rexx '' | the full name of the file (including path) |
| FileAccess = Rexx '' | the file access method requested (see below) |
| FileStatus = byte 0 | the coded File Status
|
| FileOrganisation = byte 0 | The files Organisation
|
| FileRecType = char | the record type indicator
|
| FileRecLen = int 0 | the Files record length
(if available)
|
| FileDTS = Rexx ' |
The Files Date Time Stamp (at open time) in the ISO format YYYY-MM-DD hh:mm:ss nnnn |
| existing = boolean 0 | the original value of exists() at open time.
|
| CurLine = Rexx '' | the current (last) line read/written from this File |
| CurLineNo = int 0 | the current (last) line-number read/written |
| pendingLine = boolean 0 | flag for pending line (for lines()) |
| needsUTF = boolean 0 | the UTF read/write flag
|
| FileSize = long -1 | old file-size in bytes, when available
|
| FileNumberOfLines = Int -1 | total Number of Lines of
this File, when available
|
| FileLinesBuffered = boolean 0
(when opened with ‚READ LINES‘ or ,UPDATE LINES‘) |
Flag indicating if lines of File are buffered in core
|
|
FileLines = Rexx '' |
Indexed String(=Stem) of all Lines in core, with the line-number as the index. (only filled when FileLinesBuffered is 1) |
| FileLinePosRead | the Files Line Read position (core-buffered random line I/O) |
| FileLinePosWrite | the Files Line Write position (core-buffered random line I/O only) |
| FileReadLocation = long 1 | Read Location in bytes (record oriented random files only, first byte is 1) |
| FileWriteLocation = long 1 | Write Location in bytes (record oriented random files only, first byte is 1) |
Private RexxFile Properties:
Internally, the various access methods are managed thru attached Java Input/Output streams, but the relevant RexxFile properties are currently deliberately hidden from the user, and included here for documentation purposes only.
AttachedFIS = FileInputStream null |
attached Java File-Input-stream |
AttachedBIS= BufferedInputStream null |
att. Java buffered input stream |
AttachedDIS = DataInputStream null |
attached Java Data Input Stream |
AttachedFOS = FileOutputStream null |
attached Java File-Output-Stream |
AttachedBOS = BufferedOutputStream null |
attached Java buffered output |
AttachedDOS = DataOutputStream null |
attached Java Data Output Stream |
AttachedRAF = RandomAccessFile Null |
attached Java RANDOM-File |
|
|
note that RANDOM access is only used for charin(text,start) and charout(text,start)! all other variants are resolved with buffered I/O streams (more than 10 times quicker!)
Public methods:
RexxFile has a single constructor method, RexxFile(filename), which will create a new object on every call.
method RexxFile(name=Rexx)
returns a unique RexxFile-Descriptor (FD) for a given File-name. Note, however, that each call (even with the same file name) creates a new RexxFile object. Use the RexxFile.FD(name) method (described below) to get a unique RexxFile-Object by File-Name.
method FD(name=Rexx) public static returns RexxFile
a function returning the RexxFile File descriptor (FD) of a given filename.if the object(filename) is already known, this corresponding FD is used. If not, a new RexxFile object is created.
method access(access_method=Rexx) returns RexxFile
where access_method may be one of the following
INPUT, READ |
read access (sequential) |
OUTPUT, REWRITE, REPLACE |
write access (sequential, overwriting the existing content of the file!) |
EXTEND, WRITE, APPEND |
extend access (sequential, adding records to the file) |
UPDATE |
Update acesss (sequential/random) |
when needed, the actual access method may be suffixed by one or more of the following modifiers:
RANDOM for RANDOM access (record oriented)
LINES for RANDOM access (line oriented). Note, that in the latter case all lines of the file are read into core when the ‚READ LINES‘ access-method is used, and written back to the file at file close time only!
UTF UTF8 encoding requested.
Examples:
FD_input = RexxFile.FD(;myfile.txt‘).access(‚READ‘)
Builds a unique File-descriptor for file ‚myfile.txt‘, and checks if the file exists. If ist does not exist, an appropriate error message is displayed and the program is aborted. Use the exists() method if you want to check the file first by your own.
FD_input=RexxFile.FD(‚myfile.txt‘).access(‚READ LINES‘)
Reads all lines of ‚myfile.txt‘ into core. Note that the access function does return the RexxFile object, whereas open returns a result String.
Public File Access methods:
method open(access_method) public deprecated
ancient form for access. Note that open returns ‚READY:‘, as specified for the stream function, whilst access returns a RexxFile object
method exists() returns boolean
returns boolean 1 if this.File exists, 0 if it does not exist.
method scratch() final
scratches this.File (deletes the files content, when present, otherwise creates a new empty file)
method extend() final
creates this.Filename, if file does not yet exist, and opens it for write. Appends to the file, if file does already exist
method close() final
flushes any pending buffers and closes this.file, if open. No action, if file is not open (not accessed)
method erase() public deprecated
erases (deletes) a given file. Historic, use RexxFile(fid).delete() instead.
method stream(stream_name=Rexx '', operation=Rexx '', command=Rexx '')-
public static deprecated returns Rexx
normally, all stream commands, when given literally, are translated to the proper methods by the classic Rexx to NetRexx converter. The stream function is available for applications which need to build the command strings on the fly, and are translated to the proper methods above at run time..
Inherited methods of any RexxFile object
The class RexxFile extends the Java class File, and therefore the follwowing properties and methods are inherited from the Java File class:
| exists() | a boolean returning 0 is the file does not exist, and 1 if it does exist |
| length() | the actual persistent file length (in bytes!). |
| CanRead() | true (=1), if the given file can be read |
| CanWrite() | true(=1) ,i f the given file can we written |
|
IsHidden() |
true(=1) , if the file is hidden, i.e will not be shown by the DIR command |
|
IsFile() |
true(=1) , if the given FileName designates a File. |
| IsDirectory() | true(=1) , if the given FileName designates a Directory. |
| IsAbsolute() | true(=1), if the given FileName did conatin an absule path specification |
| LastModified() | the last modification, expressed in milliseconds past 1.1.1970. But note that also the property FileDTS and the function DTS() are available,which will give you the accurate Date Time Stamp in a more meaningful notation. |
see the Java documentation for a more elaborate description of these properties and methods.
Date & Time of Last modification, FileFormat, and FileInfo:
method DTS(file=Rexx) static public returns Rexx
returns Date Time Stamp of an existing file in the format YYYY-MM-DD hh:mm:ss nnnn. Returns the null string when the file does not exist..
method FileDateTime() public deprecated returns Rexx – old American format
Historic: Date & Time of last file Modification in the american Format: returns MM/DD/YYYY hhmmss when the file exists. returns null string, when the file does not exist.
Historic, use FileDTS unstead !
method FileTimeStamp() public deprecated returns Rexx –old EUROPEAN format
Historic: Date and Time of the last file Modification in the EUROPEAN Format:.Returns YYYY-MM-DD hh:mm:ss when the file exists. Returns null string, when the file does not exist.
The routines FileDateTime and FileTimeStamp are used for upward compatibility to
other Rexx Implementations only, and should be replaced by the DTS function (or
the property FileDTS).
Line oriented I/O methods (working with the current RexxFile object)
method lines() final returns int
returns 0, if end of file is reached.
returns remaining number of lines, if this information is available.
returns 1, if number of lines is not available on this operating system, and EOF is not yet reached. .
method linein() public final returns Rexx
get next line from this.File
method linein(line_no=int) public final returns Rexx
Get line with given line number. Implies access-method ‚READ LINES‘. Note that when the file is accessed with ‚READ LINES‘ or ‚UPDATE LINES‘, the lines are already held in core and this operation is very quickl
method linein(line_no=int ,count=int 1) public final returns Rexx
Both versions imply access-method 'READ LINES'.
method lineout(oline=Rexx) public final returns int
sequential line-oriented IO: put output oline to current Output-Line-Number.
method lineout(oline=Rexx,oline_no=int) public final returns int
random line-oriented I/O: put output line to given line number; implies access(‚UPDATE LINES‘) when no access method has been specified). Also note, that when UTF-encoding is required, changed lines might also change their length. With the core buffering techniques available you will not
loose any existing information, as the new file (with UTF encoding) is written at once when the file is closed!
method lineout() public deprecated
historic; note that empty lineout is CLOSE in classic REXX!!
Character oriented I/O methods:
method chars() public final returns long
return number of remaining characters in the given RexxFile, when available. Returns 0, when EOF is encountered.Returns 1, if the number of remaining characters is not available, but EOF has been still not reached. If the designated file is the console, a null string terminates console input.
method charin() public returns Rexx
reads a bunch (chunk) of characters, starting at the current file location. Returns a null string at EOF.
Attention: this function does currently NOT read a single character, as specified in .classic Rexx‘, but a chunk of 8 Kilobytes at once to improve performance. Is this a wise decision ? Comments are welcome.
method charin(n=int) public returns Rexx
read n bytes from current File Read location.
method SeekTo(start=long) public returns long
seeks to a given starting byte location. Only available for RANDOM record oriented files.
The first byte of the file is byte 1 (not 0 like in Java). The next available FileReadLocation is returned, i.e. the next charin/recin call will start at the given location.
method charin(start=long) public returns Rexx
reads a bunch (chunk) of characters, starting at the given File-Location. The File-location is measured in bytes. First byte of File is 1 (not 0, as in Java).
method charin(start=long,n=int) public returns Rexx
reads n bytes, starting at location start, and returns it as a Rexx String..
method charout(text=Rexx) final returns int
puts out text at the current file location.
method charout(text=Rexx,start=long) final returns int
puts out text at the file-location start (in bytes, first byte is byte 1).
method charout() public deprecated
historic; empty charout is equivalent to ‚close‘ in classic REXX!
method load_lines() public
loads entire line-numbered file to core. Called internally, when access-method 'INPUT LINES', 'READ LINES', or 'UPDATE LINES' is used.
method save_lines() public
save entire line numbered file from core. Called implicitely for files opened with 'UPDATE LINES'.
method closeAllFiles() public static
Closes all opened RexxFile objects. This routine will be automaticely invoked ‚on exit‘ to ensure that all pending buffers are written back to disk. Also note, that the LOG-file, if present, is always closed as the last file!.
method erase(f=Rexx) public static deprecated
erases (deletes) a given file. Historic, use RexxFile(fid).delete() instead.
method purge(flist=Rexx) public static deprecated
Purges (erases) a list of given files. The entries are separated by a semicolon, for instance.
Historic name (of GE’s MARK III service): example:
purge(‚abc.def;myfile.xxx;c:\mydir\catalog.file‘)
no action, if the file(s) do(es) not exist.
File Description Routines:
As the original classic Rexx implementation did not specify file I/O, a couple of very similar routines have been implemented with very similar, but not indentical purposes in the various Rexx implementations.
Currently, the RexxFile package attempts to provide the union of the possible calling sequences. The overhead is very small, as each of them only need a few lines of coding.
method length(f=Rexx) static public returns long
returns length of file in bytes. Returns 0 when file does not exist.
method fullname(f=Rexx) static public returns Rexx
returns the full file name (real name) of a given file. This method is equivalent to the Java method File(file).getAbsolutePath().
If the File is null, the Full Filename is a Null string, the console is designated..
method FileFormat() public deprecated returns Rexx -- CMS QUERY format
returns FileRecType' 'FileRecLen
method FileInfo() public deprecated returns Rexx -- CMS QUERY Info
returns FileFormat() FileNumberOfLines FileDateTime()
method fileid(fn=Rexx '', ft=Rexx '',fp=Rexx '') public static returns Rexx
builds a file-id according to opsys conventions.A file-id is a unique string identifying a single file: It may either already exist, or might be created with scratch.
method parsefid(f=Rexx) public static returns Rexx
parses a given file-id (according to the operating system conventions) and returns the result in the format
fn ft fp (filename, filetype, filepath, separated by a space)
Historic, needed for CMS compatibility only.
method filename(f=Rexx) public static returns Rexx
returns the filename part of a given file-id (without the path and the file-type!!)
method filetype(f=Rexx) public static returns Rexx
returns the filetype part of a given file-id
method filepath(f=Rexx) public static returns Rexx
returns the file-path (including the drive letter!)
method ispacked(f=Rexx) public static returns boolean
tests if a file is packed (on CMS). Currently returns always 0 in Java.
method isopen(f=Rexx) public static returns boolean
returns boolean 1 if the given file has already been opened (or accessed) successfully.
method filespec(option=Rexx, f=Rexx) public static deprecated returns Rexx
the filespec function is provided for OS/2 compatibility.
Option may be one of the following:
otherwise aborts with the error-message: 'unknown option in filespec('option','spec')')
method nametype(f=Rexx) public static returns Rexx
returns the FileName including the file-type
method filedrive(f=Rexx) public static returns Rexx
returns the file-drive part of the path
method sysfileid(f=Rexx,ft=Rexx) public static returns Rexx
searches for a system file. First., it attempts to read the given file in the current directory. If the file exists, this is used. When the file does not exist in the current directory, it is searched in the directories specified in the classpath-variable. When the file exists, the routine returns the full file name (including path).
method traceio(itrace=int 1) public static
This is a debug aid setting the desired level of tracio. The available codes for itrace are:
0 = no trace1 = trace open/close/delete
2 = trace input lines
3 = trace output lines
4 = debug IO (trace all utility routines)
-1 = trace Current file changes
the function tracio may be used to debug a given program by looking at the IO it performs.
Deprecated functions/subroutines:
Deprecated STATIC methods (old classic Rexx style calling sequence with given Filename)
method exists(f=Rexx) public static deprecated returns boolean
returns boolean 1 if given file exists, 0 if it does not exist
method open(f=Rexx, access_method=Rexx '') public static deprecated
ancient form for access. Note that open returns ‚READY:‘, as specified for the stream function,
whilst access returns a RexxFile object
method read(f=Rexx) public static deprecated -- open for read
historic; does NOT read any line, but opens for read
method scratch(f=Rexx) public static deprecated
scratches given filename (deletes the files content, when present, otherwise creates a new empty file).
method append(f=Rexx) public static deprecated
creates given.filename, if file does not yet exist. Appends to the file, if file does already exist.
method close(f=Rexx) public static deprecated
flushes any pending buffers and closes given fileName, if open. No action, if file is not open (not accessed)
Deprecated Line oriented I/O functions (old classic Rexx style calling sequence)
method lines(f) public static deprecated returns int
returns 0, if end of file is reached. Returns remaining number of lines, if this information is available.
returns 1, if number of lines is not available on this operating system, and EOF is not yet reached.
method linein(f) public static deprecated returns Rexx
historic; get next line from given filename f.
method linein(f,line_no=int,count=int 1) public static deprecated returns Rexx
historic; count must be 0 or 1. When count is 1, then get line with given line-number: If count is 0, position file to given line number.
method lineout(f=Rexx,oline=Rexx) public static deprecated returns int
sequential line-oriented IO: put output oline to current Output-Line-Number of given FileName f .
Deprecated character oriented I/O functions (old classic Rexx style calling sequence)
method chars(f=Rexx) static public deprecated returns long
returns the number of remaining characters of the file.
method charin(f=Rexx) public returns Rexx
returns a bunch (chunk of size 8k) of characters, if available. Otherwise as max. characters (<8k) which are available.
method charin(f=Rexx,start=long) public deprecated returns Rexx
returns a bunch of characters, starting at location start.
method charin(f=Rexx,start=long,n=int) public deprecated returns Rexx
returns a string of n characters, starting at location start.
method charout(f=Rexx,text=Rexx) public static deprecated returns int
put characters out at current write position. No end-of-line-characters added!
method charout(f=Rexx,text=Rexx,start=long) public static deprecated returns int
set write position to start (byte locaton, first character of file is 1!), and put characters out as above.
Utility routines and minor methods:
method unpack(packed_fid, fid) public static
this method is currently un-used in Java, and only used for CMS compatibility.
Maybe we could use this method for zipped or jar‘ed files ?!?
Public static properties:
The following static properties are initialized at the first invokation of class RexxFile:
$props=System.getProperties() he system properties $classpath=$props.getProperty('java.class.path') the current Java classpath $path=$props.getProperty('java.library.path') the current library path $fs=$props.getProperty('file.separator') file separator (in a file-list) $ts='.' /* type separator */ type separator (currently always ‘.‘) $ps=$props.getProperty('path.separator') path separator $ls=$props.getProperty('line.separator') line separator $ls_length=$ls.length() length of line separator $InLine = Rexx '' most recent input line $InFile = Rexx '' FileName of most recent input file read, blank for console
$InLineno = int 0 most recent input line number, if available $InPointer = int 0 current parse pointer, if available Ready=Rexx 'READY:' Ready msg for stream command
Examples: