[comp.sys.apple2] Applesoft problem: finding the end of a text file

dunadan@blake.u.washington.edu (Steven Owen) (01/15/91)

Here's an age-old Applesoft BASIC problem that I've come across while
reworking some old code:

When reading information from a TXT file, I have yet to find a satisfactory
way to determine where the end of a file is.  The most common method, I
suppose, is to slip in an ONERR GOTO statement just before you start reading
data from the file, and reference the line number just after the read command,
which usually closes the file and changes the ONERR GOTO line number to its
original reference.

Another way is to find the file's length, and keep track of how many bytes
you've read from the file (along with each CR), and stop when the two are
equal.  This should work, except in cases where the final line of the program
isn't terminated by a RETURN character (this method would work if you're using
GETs to retrieve the data, but that would be much too slow).

To get the file's length, you can either read the file's directory entry in
its parent DIR file (messy, and if the directory is large, this can take a
while), or poke a GET_EOF MLI call into memory (faster, but still a little
messy, even when using Amperworks' neat &MLI command).

It would be nice to have a one or two-line solution, but I don't suppose that
I'm going to find something as simple as "IF <EOF> THEN ...", am I?

--Mike Owen, Bladesmith at large

ART100@PSUVM.PSU.EDU ("Andy Tefft 725-1344", 814) (01/16/91)

Under Prodos, you almost don't NEED to use the "read" command to read
text files. You have a lot of room as a programmer to read files
under prodos which you didn't have in dos 3.3. I can think of two
solutions:

1). read in chunks of the file using BLOAD with the TTXT parameter.
You can use the B and L parameters to identify which sections to read
in. You can then go through and parse out the info.
Kind of a pain for variable length records though.

2) (I haven't done one of these in a long time...) write your own
read command. Would be quite simple with a couple of mli calls...
you could even use an & command to allow some parameters. You could
set a string to the filename to use, then in assembly you would
put this string in the pathname buffer to do your mli calls.
With a proper setting of newline read mode, you can read one line
at a time. Also this routine would check for the eof condition
and return this info to your program either in some memory location
or a variable.

Well, of course, it may just be simpler to use an onerr goto.

mdavis@pro-sol.cts.com (Morgan Davis) (01/22/91)

In-Reply-To: message from dunadan@blake.u.washington.edu
 
Here's a trick for finding the end of file of a text file from
Applesoft under BASIC.SYSTEM.  It is pretty fast, and requires no
extensive error handling.
 
10 FILE$ = "your file name goes here"
20 D$ = CHR$(4) : EOF = 48840
30 PRINT D$ "APPEND" FILE$
40 PRINT D$ "CLOSE" FILE$
50 SIZE = PEEK (EOF) + PEEK (EOF + 1) * 256 + PEEK (EOF + 2) * 65536
50 PRINT FILE$ " contains " SIZE " bytes"
 
The magic here is that when you do an APPEND, BASIC.SYSTEM opens the
file and does a GET_EOF call in order to move the file pointer to
the end of the file.  After closing the file, the end of file value
is still intact at $BEC8 (48840).
 
You can make this a general purpose file-size-getter by inserting
and changing these lines:
 
25 PRINT D$ "VERIFY" FILE$
30 PRINT D$ "APPEND" FILE$ ",T" PEEK(48824)
 
After a VERIFY (which is a GET_FILE_INFO MLI call), the file's information
such as type, aux type, etc., is left intact in memory.  The only problem
with this code is that it might balk on locked files, as the APPEND
assumes a WRITE.  I haven't test it against a locked file, but you can.
 
BTW, in MD-BASIC this kind of tricky coding is amazingly simple and clean.
As an example for those of you with MD-BASIC, here is the equivalent code:
 
        File$ = "your file name goes here"
        fVerify File$
        fAppend File$ ",T" PEEK(_FIFILID)
        Size = peek24(_SEOF)
        PRINT File$ " contains " Size " bytes"
 
--Morgan Davis

UUCP: crash!pro-sol!mdavis           AOL, BIX: mdavis  
ARPA: crash!pro-sol!mdavis@nosc.mil  GEnie:    m.davis42
INET: mdavis@pro-sol.cts.com         ProLine:  mdavis@pro-sol