From: Rong Shen
Subject: a problem with reading a stream
Date: 
Message-ID: <1992Dec27.014528.17943@news.columbia.edu>
Hi experts:

	I am trying to write a function that asks a path to a file
from the user and opens the file to read. There is no problem with
opening the file, but when it tries to read, the interpreter
complains.

	Can anyone tell me why?

	Thanks very much.

--
····@cunixb.cc.columbia.edu

(defun read-path ()
  (format t "Enter the path to the file to read, e.g. /tmp/foo/faq.txt")
  (setf file-path-name (read-line))
  (setf what-stream (open file-path-name :direction :input)) ; ok

  (read what-stream nil 'This-is-the-end-of-the-world)) ; This line has error;

From: David Loewenstern
Subject: Re: a problem with reading a stream
Date: 
Message-ID: <1992Dec28.191019.18212@cbnewsl.cb.att.com>
... On Sun, 27 Dec 1992 01:45:28 GMT, ····@cunixb.cc.columbia.edu (Rong Shen) said:
} Hi experts:

Barmar must be on vacation... so a non-expert will have to handle it 8^).

}         I am trying to write a function that asks a path to a file
} from the user and opens the file to read. There is no problem with
} opening the file, but when it tries to read, the interpreter
} complains.


} (defun read-path ()
}   (format t "Enter the path to the file to read, e.g. /tmp/foo/faq.txt")
}   (setf file-path-name (read-line))
}   (setf what-stream (open file-path-name :direction :input)) ; ok

}   (read what-stream nil 'This-is-the-end-of-the-world)) ; This line has error;

Let me guess: faq.txt doesn't contain an s-expression?  Remember, READ
reads an s-expression.  You may want READ-LINE, or READ-CHAR.

Also: it's usually bad style to use OPEN.  Use WITH-OPEN-FILE instead.

(WITH-STANDARD-DISCLAIMERS
   (MAKE-INSTANCE 'Signature
         :NAME      "David Loewenstern"
         :LOCATIONS '((INTERNET ··················@att.com")
                      (INTERNET ·········@paul.rutgers.edu")
                      (AT&T "201-386-6516"))
	 :AFFILIATIONS '("AT&T Bell Labs" "Rutgers, Dept of CS")
         :SILLY-QUOTE (UNIX:SHELL "/usr/bin/fortune"))))
From: Pete Grant
Subject: Re: a problem with reading a stream
Date: 
Message-ID: <1993Jan6.013014.7927@pentagon-gw.army.mil>
In article <······················@news.columbia.edu> ····@cunixb.cc.columbia.edu (Rong Shen) writes:
>Hi experts:
>
>	I am trying to write a function that asks a path to a file
>from the user and opens the file to read. There is no problem with
>opening the file, but when it tries to read, the interpreter
>complains.
>
>	Can anyone tell me why?
>
>	Thanks very much.
>
>--
>····@cunixb.cc.columbia.edu
>
>(defun read-path ()
>  (format t "Enter the path to the file to read, e.g. /tmp/foo/faq.txt")
>  (setf file-path-name (read-line))
>  (setf what-stream (open file-path-name :direction :input)) ; ok
>
>  (read what-stream nil 'This-is-the-end-of-the-world)) ; This line has error;

1.  What is the error?  A trip into the debugger?  Returns 'THIS-IS-THE...?

2.  What's in the file you're trying to read?

3.  Suggestion:  Although (open ..) works, you should use WITH-OPEN-FILE
    e.g.,
    (with-open-file (input file-path-name)
      (loop as line = (read-line input nil nil)
            while line
            do
        (....)))

  If you use (OPEN ..), then error off, the stream is left open and can
prevent you from further attempts to read the file until you explicitly
close it.  On some machine this can be less than straightforward.  On
Symbolics you can use (FS:CLOSE-ALL-FILES).

Pete.
From: Ole Kristensen
Subject: Re: a problem with reading a stream
Date: 
Message-ID: <ok.726739371@csd.cri.dk>
·····@pentagon-gw.army.mil (Pete Grant) writes:

>In article <······················@news.columbia.edu> ····@cunixb.cc.columbia.edu (Rong Shen) writes:
>>Hi experts:
>>
>>	I am trying to write a function that asks a path to a file
>>from the user and opens the file to read. There is no problem with
>>opening the file, but when it tries to read, the interpreter
>>complains.
>>
>>	Can anyone tell me why?
>>
>>	Thanks very much.
>>
>>--
>>····@cunixb.cc.columbia.edu
>>
>>(defun read-path ()
>>  (format t "Enter the path to the file to read, e.g. /tmp/foo/faq.txt")
>>  (setf file-path-name (read-line))
>>  (setf what-stream (open file-path-name :direction :input)) ; ok
>>
>>  (read what-stream nil 'This-is-the-end-of-the-world)) ; This line has error;

>1.  What is the error?  A trip into the debugger?  Returns 'THIS-IS-THE...?

>2.  What's in the file you're trying to read?

>3.  Suggestion:  Although (open ..) works, you should use WITH-OPEN-FILE
>    e.g.,
>    (with-open-file (input file-path-name)
>      (loop as line = (read-line input nil nil)
>            while line
>            do
>        (....)))

>  If you use (OPEN ..), then error off, the stream is left open and can
>prevent you from further attempts to read the file until you explicitly
>close it.  On some machine this can be less than straightforward.  On
>Symbolics you can use (FS:CLOSE-ALL-FILES).

>Pete.



Hi Rong and Pete,

The code shown is sensible to typing errors. If the pathname
does not exist, the listener will just hang. You can test it
by issuing (read NIL NIL 'This-is-the-end). It can be avoided
by something like below:

(defun read-file (pathname)
  (let* ((in-stream (open pathname
                          :direction :input
                          :if-does-not-exist NIL))
         (contents (if in-stream
                       (read in-stream NIL NIL)
                     NIL)))
    (progn
       (if in-stream
           (close in-stream)
         (pprint (list "read-file, no stream" pathname)))
       contents)))


The above function only returns the first S-expression in the file.


Best regards,

Ole

A
A