Lisp HUG Maillist Archive

Unexpected (for me) behaviour of bivalent streams

On Windows with this function

  (defun foo (pathspec)
    (with-open-file (out pathspec
                         :direction :output
                         :if-exists :supersede)
      (write-sequence (make-array 1
                                  :element-type '(unsigned-byte 8)
                                  :initial-element 10)
                      out))
    (with-open-file (in pathspec)
      (file-length in)))

the result of, say, (FOO "/tmp/foo.txt") is 2 although only one octet
was seemingly written to the stream.

I can see how this happens - the stream is a bivalent stream and
binary data written to the stream is treated like character data, so
the 10 is viewed like a #\Newline character and converted to the CRLF
combo.

However, I find this kind of counter-intuitive.  Furthermore, there
seems to be no way to write a single literal octet "10" to the string,
so in that sense the stream isn't fully "bivalent."

What do others think?

And what does LispWorks think?  Is this the intended behaviour?

Thanks,
Edi.


Re: Unexpected (for me) behaviour of bivalent streams

Unable to parse email body. Email id is 4878

Re: Unexpected (for me) behaviour of bivalent streams

Hi Dave!

On Mon, 28 Nov 2005 12:34:47 GMT, davef@lispworks.com wrote:

> LispWorks FILE-LENGTH does not take account of the external format
> of its argument stream - it simply returns the number of bytes in
> the file. As an alternative
>
> (defun foo (pathspec)
>   (with-open-file (out pathspec
> 		       :direction :output
> 		       :if-exists :supersede)
>     (write-sequence (make-array 1
> 				:element-type '(unsigned-byte 8)
> 				:initial-element 10)
> 		    out))
>   (with-open-file (in pathspec)
>     (LENGTH (HCL:FILE-STRING in))))
>
> returns 1 as you expect.

Yes, but I was already taking into account that FILE-LENGTH counts
octets.  I was expecting the file two be one /octet/ long, not one
/character/.

But thanks for mentioning FILE-STRING.  One of the many nice utility
functions I tend to forget (and thus have to rewrite) from time to
time... :)

> To do that you should use a binary stream or a character stream with
> external format containing :EOL-STYLE :LF to avoid line-terminator
> conversion.

Yeah, I'm aware of that.  I had just hoped that regardless of the
external format (WRITE-BYTE x) (or rather the WRITE-SEQUENCE
equivalent) wouldn't behave like (WRITE-CHAR (CODE-CHAR x)).

Thanks,
Edi.


Updated at: 2020-12-10 08:49 UTC