Hi
this is probably a FAQ. Suppose I have something like
(setf s (open "foo.dat" :element-type 'unsigned-
byte :direction :input))
(if (am-I-at-the-eof-p s) (do-eof-stuff s) (do-some-other-stuff
s))
I am looking for a portable way to write AM-I-AT-THE-EOF-P. For (non
interactive) character streams LISTEN will do, and probably it will as
well on binary streams, but maybe there are better ways.
Cheers
--
Marco
P� Fri, 08 Feb 2008 13:02:50 +0100, skrev Marco Antoniotti
<·······@gmail.com>:
> Hi
>
> this is probably a FAQ. Suppose I have something like
>
> (setf s (open "foo.dat" :element-type 'unsigned-
> byte :direction :input))
> (if (am-I-at-the-eof-p s) (do-eof-stuff s) (do-some-other-stuff
> s))
>
> I am looking for a portable way to write AM-I-AT-THE-EOF-P. For (non
> interactive) character streams LISTEN will do, and probably it will as
> well on binary streams, but maybe there are better ways.
>
> Cheers
> --
> Marco
Found this code lying around. Should give you an idea.
The key is a optional 3'rd and 4'th argument to read-line.
Look up read-line in CLHS 21.2
(defun count-lines-file ()
(let ((sz 0) (p (parse-namestring dictionary-file)))
(with-open-file (s p :direction :input)
(do ((l (read-line s) (read-line s nil 'eof)))
((eq l 'eof) sz)
(incf sz)))))
--------------
John Thingstad
On Feb 8, 2:24 pm, "John Thingstad" <·······@online.no> wrote:
> På Fri, 08 Feb 2008 13:02:50 +0100, skrev Marco Antoniotti
> <·······@gmail.com>:
>
>
>
> > Hi
>
> > this is probably a FAQ. Suppose I have something like
>
> > (setf s (open "foo.dat" :element-type 'unsigned-
> > byte :direction :input))
> > (if (am-I-at-the-eof-p s) (do-eof-stuff s) (do-some-other-stuff
> > s))
>
> > I am looking for a portable way to write AM-I-AT-THE-EOF-P. For (non
> > interactive) character streams LISTEN will do, and probably it will as
> > well on binary streams, but maybe there are better ways.
>
> > Cheers
> > --
> > Marco
>
> Found this code lying around. Should give you an idea.
> The key is a optional 3'rd and 4'th argument to read-line.
>
> Look up read-line in CLHS 21.2
>
> (defun count-lines-file ()
> (let ((sz 0) (p (parse-namestring dictionary-file)))
> (with-open-file (s p :direction :input)
> (do ((l (read-line s) (read-line s nil 'eof)))
> ((eq l 'eof) sz)
> (incf sz)))))
>
> --------------
> John Thingstad
READ-LINE is for character streams. In this case it is relatively
easy to use LISTEN. But I asked for binary files.
Cheers
--
Marco
P� Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti
<·······@gmail.com>:
>
> READ-LINE is for character streams. In this case it is relatively
> easy to use LISTEN. But I asked for binary files.
>
Sorry that wasn't entirly clear. You read a binary fine using
read-sequence.
Then if the returned position is less than the sequence length then you
have reached the end of the file.
From the spec:
Position is the index of the first element of sequence that was not
updated, which might be less than end because the end of file was reached.
--------------
John Thingstad
On Feb 8, 3:15 pm, "John Thingstad" <·······@online.no> wrote:
> På Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti
> <·······@gmail.com>:
>
>
>
> > READ-LINE is for character streams. In this case it is relatively
> > easy to use LISTEN. But I asked for binary files.
>
> Sorry that wasn't entirly clear. You read a binary fine using
> read-sequence.
> Then if the returned position is less than the sequence length then you
> have reached the end of the file.
>
> From the spec:
> Position is the index of the first element of sequence that was not
> updated, which might be less than end because the end of file was reached.
>
Yes. But you are assuming that I want to "bufferize" the file using
READ-SEQUENCE. I may want to use READ-BYTE.
Let me rephrase it. Can I test for the end of file on a binary file
without doing a "read"? (I.e. without doing anything that will cause
me to cache what I read if not at the EOF.)
It seems to me that the thing that gets closest is to use the FILE-
POSITION vs. FILE-LENGTH test.
Cheers
--
Marco
Marco Antoniotti <·······@gmail.com> writes:
> On Feb 8, 3:15�pm, "John Thingstad" <·······@online.no> wrote:
>> P� Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti �
>> <·······@gmail.com>:
>>
>>
>>
>> > READ-LINE is for character streams. �In this case it is relatively
>> > easy to use LISTEN. �But I asked for binary files.
>>
>> Sorry that wasn't entirly clear. You read a binary fine using �
>> read-sequence.
>> Then if the returned position is less than the sequence length then you �
>> have reached the end of the file.
>>
>> �From the spec:
>> Position is the index of the first element of sequence that was not �
>> updated, which might be less than end because the end of file was reached.
>>
>
> Yes. But you are assuming that I want to "bufferize" the file using
> READ-SEQUENCE. I may want to use READ-BYTE.
Of course, READ-BYTE has the same parameters as READ. Use (READ-BYTE stream nil 'eof).
> Let me rephrase it. Can I test for the end of file on a binary file
> without doing a "read"? (I.e. without doing anything that will cause
> me to cache what I read if not at the EOF.)
No, you cannot. End of file is not a status, it's a
condition. Something that happens at a given time, and that can go
back to false the next moment.
> It seems to me that the thing that gets closest is to use the FILE-
> POSITION vs. FILE-LENGTH test.
But it gives wrong results, when you don't have exclusive access to
the file, or when it's not a regular file, because FILE-LENGTH can
change any time.
--
__Pascal Bourguignon__
On Feb 8, 4:04 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Marco Antoniotti <·······@gmail.com> writes:
> > On Feb 8, 3:15 pm, "John Thingstad" <·······@online.no> wrote:
> >> På Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti
> >> <·······@gmail.com>:
>
> >> > READ-LINE is for character streams. In this case it is relatively
> >> > easy to use LISTEN. But I asked for binary files.
>
> >> Sorry that wasn't entirly clear. You read a binary fine using
> >> read-sequence.
> >> Then if the returned position is less than the sequence length then you
> >> have reached the end of the file.
>
> >> From the spec:
> >> Position is the index of the first element of sequence that was not
> >> updated, which might be less than end because the end of file was reached.
>
> > Yes. But you are assuming that I want to "bufferize" the file using
> > READ-SEQUENCE. I may want to use READ-BYTE.
>
> Of course, READ-BYTE has the same parameters as READ. Use (READ-BYTE stream nil 'eof).
>
> > Let me rephrase it. Can I test for the end of file on a binary file
> > without doing a "read"? (I.e. without doing anything that will cause
> > me to cache what I read if not at the EOF.)
>
> No, you cannot. End of file is not a status, it's a
> condition. Something that happens at a given time, and that can go
> back to false the next moment.
Not what the ANSI spec says in the glossary. But I see your point.
>
> > It seems to me that the thing that gets closest is to use the FILE-
> > POSITION vs. FILE-LENGTH test.
>
> But it gives wrong results, when you don't have exclusive access to
> the file, or when it's not a regular file, because FILE-LENGTH can
> change any time.
There are other ways of ensuring exclusiveness when "accessing" a
file. Suppose you do. Is the check (<= (file-length f) (file-
position f)) the best bet? In other words, how do I do C feof()?
Cheers
--
Marco
Marco Antoniotti <·······@gmail.com> writes:
>> > It seems to me that the thing that gets closest is to use the FILE-
>> > POSITION vs. FILE-LENGTH test.
>>
>> But it gives wrong results, when you don't have exclusive access to
>> the file, or when it's not a regular file, because FILE-LENGTH can
>> change any time.
>
> There are other ways of ensuring exclusiveness when "accessing" a
> file. Suppose you do. Is the check (<= (file-length f) (file-
> position f)) the best bet? In other words, how do I do C feof()?
feof(3) just returns a flag that is set by the stdio routines that
call read(2) and get a eof-value.
There is no eof(2) syscall!
Note how the POSIX specification for feof avoid mentioning anything
about the actual "end of the file", but refers only the end-of-file
indicator of the stream. This indicator is set to true when read(2)
returned the eof value (in the case of read(2), like read-sequence,
it's a read size less than the asked size).
http://opengroup.org/onlinepubs/007908799/xsh/feof.html
--
__Pascal Bourguignon__
On Feb 8, 5:17 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Marco Antoniotti <·······@gmail.com> writes:
> >> > It seems to me that the thing that gets closest is to use the FILE-
> >> > POSITION vs. FILE-LENGTH test.
>
> >> But it gives wrong results, when you don't have exclusive access to
> >> the file, or when it's not a regular file, because FILE-LENGTH can
> >> change any time.
>
> > There are other ways of ensuring exclusiveness when "accessing" a
> > file. Suppose you do. Is the check (<= (file-length f) (file-
> > position f)) the best bet? In other words, how do I do C feof()?
>
> feof(3) just returns a flag that is set by the stdio routines that
> call read(2) and get a eof-value.
>
> There is no eof(2) syscall!
>
> Note how the POSIX specification for feof avoid mentioning anything
> about the actual "end of the file", but refers only the end-of-file
> indicator of the stream. This indicator is set to true when read(2)
> returned the eof value (in the case of read(2), like read-sequence,
> it's a read size less than the asked size).http://opengroup.org/onlinepubs/007908799/xsh/feof.html
>
Yes. And you simulated this effect in your other post with the FILE
struct.
Reading the POSIX and ISO-C specs made me think that feof() is used
only ex-post alongside ferror() to see what happened when a read
operation went awry. So, probably I will have to change my logic
after all.
Cheers
--
Marco
On Feb 8, 5:54 pm, Marco Antoniotti <·······@gmail.com> wrote:
> On Feb 8, 5:17 pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>
>
>
> > Marco Antoniotti <·······@gmail.com> writes:
> > >> > It seems to me that the thing that gets closest is to use the FILE-
> > >> > POSITION vs. FILE-LENGTH test.
>
> > >> But it gives wrong results, when you don't have exclusive access to
> > >> the file, or when it's not a regular file, because FILE-LENGTH can
> > >> change any time.
>
> > > There are other ways of ensuring exclusiveness when "accessing" a
> > > file. Suppose you do. Is the check (<= (file-length f) (file-
> > > position f)) the best bet? In other words, how do I do C feof()?
>
> > feof(3) just returns a flag that is set by the stdio routines that
> > call read(2) and get a eof-value.
>
> > There is no eof(2) syscall!
>
> > Note how the POSIX specification for feof avoid mentioning anything
> > about the actual "end of the file", but refers only the end-of-file
> > indicator of the stream. This indicator is set to true when read(2)
> > returned the eof value (in the case of read(2), like read-sequence,
> > it's a read size less than the asked size).http://opengroup.org/onlinepubs/007908799/xsh/feof.html
>
> Yes. And you simulated this effect in your other post with the FILE
> struct.
>
> Reading the POSIX and ISO-C specs made me think that feof() is used
> only ex-post alongside ferror() to see what happened when a read
> operation went awry. So, probably I will have to change my logic
> after all.
If you know that no one will be changing your file while you're
accessing it, then I think you'd be fine doing
(defun eofp (binary-file-stream)
(= (file-position binary-file-stream) (file-length binary-file-
stream)))
if not, then yeah, you should change your logic. Or wrap read-byte
with a function that checks for eof and sets a flag in a weak hash-
table, and make your eofp function just look up streams there.
Marco Antoniotti <·······@gmail.com> wrote:
+---------------
| ····@informatimago.com (Pascal J. Bourguignon) | wrote:
| > feof(3) just returns a flag that is set by the stdio routines that
| > call read(2) and get a eof-value.
| >
| > There is no eof(2) syscall!
| >
| > Note how the POSIX specification for feof avoid mentioning anything
| > about the actual "end of the file", but refers only the end-of-file
| > indicator of the stream. �This indicator is set to true when read(2)
| > returned the eof value ...
|
| Yes. And you simulated this effect in your other post with the FILE
| struct.
|
| Reading the POSIX and ISO-C specs made me think that feof() is used
| only ex-post alongside ferror() to see what happened when a read
| operation went awry. So, probably I will have to change my logic
| after all.
+---------------
(*sigh*) Yes, probably. You wouldn't if LISTEN worked "properly",
but it doesn't [can't?], at least not on Unix/Linux systems.
Function LISTEN
...
If an end of file is encountered, listen returns NIL..
This has two problems:
1. LISTEN should really be defined as being READ-WOULD-NOT-HANG (IMHO),
and if defined that way then on EOF it would return T, not NIL,
the way BSD "listen()" does.[1] And a subsequent READ *wouldn't*
hang, but get an instant EOF.
2. The CLHS quote above speaks of the end of file being "encountered",
without answering "encountered by whom?", which implies that a call
to LISTEN might not be enough to "encounter" the EOF, leaving the
implementation free to do weird things like this, where "tmp2" is
a file with three lines in it:
> (with-open-file (s "tmp2")
(list (read-line s nil 'my-eof)
(read-line s nil 'my-eof)
(read-line s nil 'my-eof)
(listen s)
(read-line s nil 'my-eof)
(listen s)))
("foo" "bar" "baz" T MY-EOF NIL)
>
It's not until the EOF was "encountered" by the 4th READ-LINE
that LISTEN was informed of the EOF (via internal side-channel).
And, of course, as Pascal suggests, that's probably because
there's no "eof(2)" syscall on this system, a Unix/Linux.
Oh, well...
-Rob
[1] BSD-style "select()" at least *does* give you a "readable"
indication on a socket EOF, which means that if you "select()"
before every "read()" you can almost get what you want.
Trouble is, you can't use this approach everywhere, since
there are some Linux "/proc" files that *never* return
"readable" indications from "select()", even when a "read()"
would *not* block! But that's a battle for another day...
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
P� Fri, 08 Feb 2008 15:15:34 +0100, skrev John Thingstad
<·······@online.no>:
> P� Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti
> <·······@gmail.com>:
>
>>
>> READ-LINE is for character streams. In this case it is relatively
>> easy to use LISTEN. But I asked for binary files.
>>
>
> Sorry that wasn't entirly clear. You read a binary fine using
> read-sequence.
> Then if the returned position is less than the sequence length then you
> have reached the end of the file.
>
> From the spec:
> Position is the index of the first element of sequence that was not
> updated, which might be less than end because the end of file was
> reached.
>
If you wonder why there is no generic function for reporting the end of
file character it is that (the ASCII character 127) EOF is usually only
inserted in text files not binary files. This is why your request seems
odd.
--------------
John Thingstad
On Feb 8, 3:29 pm, "John Thingstad" <·······@online.no> wrote:
> På Fri, 08 Feb 2008 15:15:34 +0100, skrev John Thingstad
> <·······@online.no>:
>
>
>
> > På Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti
> > <·······@gmail.com>:
>
> >> READ-LINE is for character streams. In this case it is relatively
> >> easy to use LISTEN. But I asked for binary files.
>
> > Sorry that wasn't entirly clear. You read a binary fine using
> > read-sequence.
> > Then if the returned position is less than the sequence length then you
> > have reached the end of the file.
>
> > From the spec:
> > Position is the index of the first element of sequence that was not
> > updated, which might be less than end because the end of file was
> > reached.
>
> If you wonder why there is no generic function for reporting the end of
> file character it is that (the ASCII character 127) EOF is usually only
> inserted in text files not binary files. This is why your request seems
> odd.
>
I know. That is why I am asking if there is a better way.
Cheers
--
Marco
P� Fri, 08 Feb 2008 15:38:10 +0100, skrev Marco Antoniotti
<·······@gmail.com>:
> On Feb 8, 3:29�pm, "John Thingstad" <·······@online.no> wrote:
>> P� Fri, 08 Feb 2008 15:15:34 +0100, skrev John Thingstad �
>> <·······@online.no>:
>>
>>
>>
>> > P� Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti �
>> > <·······@gmail.com>:
>>
>> >> READ-LINE is for character streams. �In this case it is relatively
>> >> easy to use LISTEN. �But I asked for binary files.
>>
>> > Sorry that wasn't entirly clear. You read a binary fine using �
>> > read-sequence.
>> > Then if the returned position is less than the sequence length then
>> you �
>> > have reached the end of the file.
>>
>> > �From the spec:
>> > Position is the index of the first element of sequence that was not �
>> > updated, which might be less than end because the end of file was �
>> > reached.
>>
>> If you wonder why there is no generic function for reporting the end of
>> �
>> file character it is that (the ASCII character 127) EOF is usually only
>> �
>> inserted in text files not binary files. This is why your request seems
>> �
>> odd.
>>
>
> I know. That is why I am asking if there is a better way.
Well you have, (read-byte s nil 'eof) as well as read-char.
They ALL take the optional second and third argument.
If you don't want any special treatment of EOF use the file-length.
Remember it measures the length in element-type for the stream for binary
files.
So set the :element-type to (byte 8) when opening the file for read-byte
to work correctly.
--------------
John Thingstad
On Feb 8, 4:17 pm, "John Thingstad" <·······@online.no> wrote:
> På Fri, 08 Feb 2008 15:38:10 +0100, skrev Marco Antoniotti
> <·······@gmail.com>:
>
>
>
> > On Feb 8, 3:29 pm, "John Thingstad" <·······@online.no> wrote:
> >> På Fri, 08 Feb 2008 15:15:34 +0100, skrev John Thingstad
> >> <·······@online.no>:
>
> >> > På Fri, 08 Feb 2008 14:51:54 +0100, skrev Marco Antoniotti
> >> > <·······@gmail.com>:
>
> >> >> READ-LINE is for character streams. In this case it is relatively
> >> >> easy to use LISTEN. But I asked for binary files.
>
> >> > Sorry that wasn't entirly clear. You read a binary fine using
> >> > read-sequence.
> >> > Then if the returned position is less than the sequence length then
> >> you
> >> > have reached the end of the file.
>
> >> > From the spec:
> >> > Position is the index of the first element of sequence that was not
> >> > updated, which might be less than end because the end of file was
> >> > reached.
>
> >> If you wonder why there is no generic function for reporting the end of
> >>
> >> file character it is that (the ASCII character 127) EOF is usually only
> >>
> >> inserted in text files not binary files. This is why your request seems
> >>
> >> odd.
>
> > I know. That is why I am asking if there is a better way.
>
> Well you have, (read-byte s nil 'eof) as well as read-char.
> They ALL take the optional second and third argument.
> If you don't want any special treatment of EOF use the file-length.
> Remember it measures the length in element-type for the stream for binary
> files.
> So set the :element-type to (byte 8) when opening the file for read-byte
> to work correctly.
I know about the eofp and eof-value arguments to the READ* functions.
I am looking for something else. Something along the lines of C
feof() for binary files.
Suppose I have a file-stream F with three (unsigned-byte 8) bytes in.
I do
(dotimes (i 3) (read-byte F))
Nothing happens to the open file-stream F at this point.
How can I write a function that tells me
(at-end-of-file-p F) ==> T
However, without writing
(defun at-end-of-file-p (f)
(null (read-byte f nil nil))))
Cheers
--
Marco
Marco Antoniotti <·······@gmail.com> writes:
> I know about the eofp and eof-value arguments to the READ* functions.
> I am looking for something else. Something along the lines of C
> feof() for binary files.
Ah well, that's a better way to put it.
(defstruct FILE ; like stdio FILE handle...
stream
eof)
(defun FILE-open (&rest args)
(make-FILE :stream (apply open args)))
(defun FILE-close (file)
(close (FILE-stream file)))
(defun FILE-read-sequence (file sequence &optional (start 0) (end nil))
(let ((position (read-sequence (FILE-stream file) sequence :start start :end end)))
(setf (FILE-eof file) (= position (or end (length sequence))))
position))
(defun FILE-write-sequence (file sequence &optional (start 0) (end nil))
(setf (FILE-eof file) nil)
(write-sequence (FILE-stream file) sequence))
> Suppose I have a file-stream F with three (unsigned-byte 8) bytes in.
> I do
>
> (dotimes (i 3) (read-byte F))
(defun FILE-read-byte (file)
(let ((result (read-byte (FILE-stream) nil file)))
(if (eq result file)
(progn (setf (FILE-eof file) t)
;; what byte to return???
nil)
result)))
> Nothing happens to the open file-stream F at this point.
> How can I write a function that tells me
>
> (at-end-of-file-p F) ==> T
(defun at-end-of-file-p (F)
(FILE-eof F))
--
__Pascal Bourguignon__
"John Thingstad" <·······@online.no> writes:
> If you wonder why there is no generic function for reporting the end
> of file character it is that (the ASCII character 127) EOF is usually
> only inserted in text files not binary files. This is why your
> request seems odd.
In ASCII, 127 is the DEL control code (usually produced by the [DELETE] key).
There is no such EOF character. Even in POSIX, EOF is defined as
(int)-1, not as a char, and that's why getc(3) and getchar(3) return
an int and not a char.
Sometimes, the ASCII control code SUB (substitute) has been misused to
indicate that the rest of the block wasn't logically in the text file,
but that was only on underpar (Kenny would call them, yobbo-)
monitors, not on any real operating system.
--
__Pascal Bourguignon__
* Marco Antoniotti Wrote on Fri, 8 Feb 2008 04:02:50 -0800 (PST):
| this is probably a FAQ. Suppose I have something like
|
| (setf s (open "foo.dat" :element-type 'unsigned-
| byte :direction :input))
| (if (am-I-at-the-eof-p s) (do-eof-stuff s) (do-some-other-stuff
| s))
[google really messes up wrapping lisp code]
| I am looking for a portable way to write AM-I-AT-THE-EOF-P. For (non
| interactive) character streams LISTEN will do, and probably it will as
| well on binary streams, but maybe there are better ways.
|
How about
(handler-case (do-some-other-stuff s)
(end-of-file (c)
(do-eof-stuff s)))
It'll work when do-other-stuff calls READ to reach eof.
--
Madhu
On Feb 8, 2:06 pm, Madhu <·······@meer.net> wrote:
> * Marco Antoniotti Wrote on Fri, 8 Feb 2008 04:02:50 -0800 (PST):
>
> | this is probably a FAQ. Suppose I have something like
> |
> | (setf s (open "foo.dat" :element-type 'unsigned-
> | byte :direction :input))
> | (if (am-I-at-the-eof-p s) (do-eof-stuff s) (do-some-other-stuff
> | s))
>
> [google really messes up wrapping lisp code]
>
> | I am looking for a portable way to write AM-I-AT-THE-EOF-P. For (non
> | interactive) character streams LISTEN will do, and probably it will as
> | well on binary streams, but maybe there are better ways.
> |
>
> How about
>
> (handler-case (do-some-other-stuff s)
> (end-of-file (c)
> (do-eof-stuff s)))
>
> It'll work when do-other-stuff calls READ to reach eof.
Nope. Not what I want. In this case you are tying the EOF detection
to the actually running of DO-SOME-OTHER-STUFF. I don't want that. I
am beginning to suspect that this is difficult even for regular
files. Maybe a reasonable test is
(= (file-position s) (file-length s))
Of course assuming that you get reasonable values for FILE-POSITION
and FILE-LENGTH as per the ANSI spec.
Cheers
--
Marco
Marco Antoniotti <·······@gmail.com> writes:
> On Feb 8, 2:06�pm, Madhu <·······@meer.net> wrote:
>> * Marco Antoniotti Wrote on Fri, 8 Feb 2008 04:02:50 -0800 (PST):
>>
>> | this is probably a FAQ. �Suppose I have something like
>> |
>> | � � (setf s (open "foo.dat" :element-type 'unsigned-
>> | byte :direction :input))
>> | � � (if (am-I-at-the-eof-p s) (do-eof-stuff s) (do-some-other-stuff
>> | s))
>>
>> [google really messes up wrapping lisp code]
>>
>> | I am looking for a portable way to write AM-I-AT-THE-EOF-P. �For (non
>> | interactive) character streams LISTEN will do, and probably it will as
>> | well on binary streams, but maybe there are better ways.
>> |
>>
>> How about
>>
>> � (handler-case (do-some-other-stuff s)
>> � � (end-of-file (c)
>> � � � �(do-eof-stuff s)))
>>
>> It'll work when do-other-stuff calls READ to reach eof.
>
> Nope. Not what I want. In this case you are tying the EOF detection
> to the actually running of DO-SOME-OTHER-STUFF. I don't want that. I
> am beginning to suspect that this is difficult even for regular
> files. Maybe a reasonable test is
>
> (= (file-position s) (file-length s))
>
> Of course assuming that you get reasonable values for FILE-POSITION
> and FILE-LENGTH as per the ANSI spec.
Well you cannot count on that.
But even if you could, (= (file-position s) (file-length s)) would
still be meaningless, because files may be appended to or truncated at
the same time you're reading them. That's why the only safe and
practical way to detect EOF, is to try to READ.
You can use (if (eq stream (READ stream T stream))
(progn ;; EOF reached
;; Note that already you cannot assert
;; (= (file-position s) (file-length s))
;; since some other process might have appended some bytes.
)
(progn ;; Got something. Not eof yet.
))
or HANDLER-CASE as shown above.
--
__Pascal Bourguignon__