This is G o o g l e's cache of http://home.earthlink.net/~neilbawd/readfile.html.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:T1xvcDHZHtwC:home.earthlink.net/~neilbawd/readfile.html+&hl=en&ie=UTF-8


Google is not affiliated with the authors of this page nor responsible for its content.

How to read a file

How to read a file

Get TEXT
 

To read a file, we need a file ID, a buffer where a record can be read, and the maximum number of characters to be read at one time.

We use VALUE to give us names for these.

Program Text 1
    0 VALUE Input-File
    0 VALUE Input-Line
    0 VALUE Input-Length


The "values" for these VALUE names should be assigned when the file is opened.

Program Text 2
    128 CONSTANT |Input-Length|

    CREATE |Input-Line|   |Input-Length| 2 + CHARS ALLOT

    : OPEN-INPUT            ( str len -- )
        R/O OPEN-FILE ABORT" Can't Open File. " TO Input-File
        |Input-Line| TO Input-Line
        |Input-Length| TO Input-Length ;


str len is the file name, and is given in the form

    S" filename"

or

    CREATE <file> ," filename"
    ...
    <file> COUNT

or is extracted from input or existing data.

Most contemporary applications process one file at a time, so OPEN-INPUT can be used successively. When a larger buffer is needed, an alternative version of OPEN-INPUT can be made, for example, OPEN-HTML-INPUT or OPEN-GRAPHIC-INPUT.

READ-INPUT gets a record implicitly using Input-File, Input-Line and Input-Length. READ-INPUT returns str len more, where str is the address of the record, len is how much was read, and more is true when there is more of the file to be read. The linebreak character is not included in the record.

Program Text 3
    : READ-INPUT            ( -- str len more )
        Input-Line dup Input-Length Input-File READ-LINE
            ABORT" Can't READ-LINE " ;


Let's also have a function to reposition a file at its beginning, and one to close a file when we are done with it.

Program Text 4
    : REWIND-FILE ( file-id -- ior ) 0 0 ROT REPOSITION-FILE ;

    : REWIND-INPUT          ( -- )
        Input-File REWIND-FILE ABORT" Can't REWIND-FILE " ;

    : CLOSE-INPUT           ( -- )
        Input-File CLOSE-FILE ABORT" Can't CLOSE-FILE " ;


From this we get a simple pattern for processing files.

    REWIND-INPUT                      ( )
    BEGIN  READ-INPUT WHILE           ( str len)
        process a record of the file  ( )
    REPEAT 2DROP
    CLOSE-INPUT

This pattern occurs frequently enough to have an even simpler form:

    TRAVERSE-INPUT                    ( str len)
        process a record of the file  ( )
    REPEAT
    CLOSE-INPUT

TRAVERSE-INPUT is a macro and can be defined with EVALUATE

    : TRAVERSE-INPUT        ( C: -- orig dest )( -- str len )
        S" REWIND-INPUT  BEGIN  READ-INPUT  ?dup AND ?dup AND WHILE "
        EVALUATE ; IMMEDIATE

or POSTPONE.

Program Text 5
    : TRAVERSE-INPUT        ( C: -- orig dest )( -- str len )
        POSTPONE REWIND-FILE
        POSTPONE BEGIN  POSTPONE READ-INPUT  POSTPONE ?DUP
        POSTPONE AND  POSTPONE ?DUP  POSTPONE AND  POSTPONE WHILE
        ; IMMEDIATE


Here are some convenient little tools. #Chars/Line is number of characters per line.

Program Text 6
    72 VALUE #Chars/Line

    : EMITS  ( n char -- ) SWAP 0 ?DO  dup EMIT  LOOP DROP ;

    : SHOW-INPUT            ( -- )
        TRAVERSE-INPUT  TYPE CR  REPEAT ;

    : LISTING               ( str len -- )
        CR ." \ "  #Chars/Line [char] # EMITS CR
        CR ." \ "  8 SPACES  2dup TYPE CR
        CR ." \ "  #Chars/Line [char] # EMITS CR
        OPEN-INPUT  SHOW-INPUT  CLOSE-INPUT ;



Glossary

Input-File          ( -- file-id )
file-id of normal input.
Input-Line          ( -- addr )
Address of normal input buffer.
Input-Length        ( -- n )
The maximum number of characters to be read at one time in normal input.
|Input-Length|      ( -- n )
The default for Input-Length.
|input-Line|        ( -- addr )
The default for Input-Line.
OPEN-INPUT          ( str len -- )
Open file str len for Input-File, set Input-Length and Input-Line to defaults.
READ-INPUT          ( -- str len more )
Get a record implicitly using Input-File, Input-Line and Input-Length. READ-INPUT returns str len more, where str is the address of the record, len is how much was read, and more is true when there is more of the file to be read. The linebreak character is not included in the record.
REWIND-FILE         ( file-id -- ior )
Reposition file-id at its beginning. Return I/O error code.
REWIND-INPUT        ( -- )
Rewind Input-File and check for I/O error.
TRAVERSE-INPUT      ( C: -- orig dest )( -- str len )
Rewind Input-File and begin loop. Each iteration reads a record and checks for more. When there is more, returns str len, where str is address of the record, and len is the length of what was read. When there is no more, the loop is terminated by REPEAT or <test> UNTIL <action> THEN.
SHOW-INPUT          ( -- )
Display records of Input-File.
LISTING             ( str len -- )
Display a heading for str len, open file str len as Input-File, and display records.
Program Text 7
(
--
Wil Baden  Costa Mesa, California  Per neilbawd@earthlink.net
)

Go back to home page.