I'm a relative Lisp newbie, and for the past several hours have been struggling with opening a binary file, and reading the data back as a series of 6-bit bytes. The line that has been giving me problems is:
<cspen...@interchange.ubc.ca> wrote: >Hi there folks -
>I'm a relative Lisp newbie, and for the past several hours have been >struggling with opening a binary file, and reading the data back as a >series of 6-bit bytes. The line that has been giving me problems is:
mas...@alum.mit.edu (JP Massar) writes: > <cspen...@interchange.ubc.ca> wrote: > > (setq stream (open "foo" :element-type '(unsigned-byte 6))) > > *** - file #P"/home/cspencer/foo" is not an integer file
> This may depend on the Lisp you are using and the OS.
Some OS's only let you open certain files in certain modes.
In general, I'd expect it will read in a given element-type a file that it itself has written in the same element-type in the same implementation of Lisp with the same volume of the same file host using the same OS. Any change to any of these and I'd expect the possibility of failure outside a few narrowly defined types.
For example, if you use (UNSIGNED-BYTE 6), you may be assuming you're taking a set of 32 bits and partitioninig it like this:
where it wastes the last two bits of every byte. (Or it might put the byte padded at the right end instead of the left end.) Such a file must be read/written by Lisp since only the implementation knows what it will do in terms of padding and endian issues in the case that it's not one of the "good" element-types.
The spec details a few good element-types that are expected to work in natural ways so that you can read a file written not-by-Lisp, but it doesn't include (unsigned-byte 6).
* Cory Spencer <cspen...@interchange.ubc.ca> | I'm a relative Lisp newbie, and for the past several hours have been | struggling with opening a binary file, and reading the data back as a | series of 6-bit bytes. The line that has been giving me problems is: | | (setq stream (open "foo" :element-type '(unsigned-byte 6))) | | and whever it executes, always prints something along the lines of: | | *** - file #P"/home/cspencer/foo" is not an integer file | | Grr. Could someone please point out the error of my ways?
You seem to be using CLISP, but have not used CLISP to write the file. CLISP supports arbitrarily sized bytes in a file by starting the file with the number of bytes as a 32-bit binary number. It is so sad that Unix does not support file meta-information. It does not keep the byte size in the file similarly, so if you lie to open about the element-type, you will run into a mismatch between the stored size and the actual size in terms of specified byte size, but fortunately, this does not apply to multiples-of-8-bit-byte files. If you want to read 6-bit bytes from a file that does not begin with the prerequisite prefix, you need to copy its contents to a new file that startes with the 32-bit prefix. Since you cannot change the element-type of a stream in mid-flight, you may need to write four 8-bit 0 bytes to your output file, copy the input file as 8-bit bytes, then reopen as a 32-bit file in overwrite mode, and write the file size of the input file in 6-bit bytes. Pretty damn ugly, but such is life when people make bad technical decisions.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.