ファイルから4byteの整数を読みだす

[code]

    (with-open-file (s f :direction :input :element-type 'unsigned-byte)
      (let ((x (make-array 4 :element-type 'unsigned-byte)))
        (read-sequence x s)
        x))
    
[/code]

このようにファイルから変数xに4byte読みだすことは出来たのですが，それを4byteの整数に変換するにはどうすればよいのでしょうか．  
あるいは4byteの整数として直接読み込むことが出来るのでしょうか？

補足：  
wavファイルをparseするコードを自分で書こうと思って質問しました。  
wavファイルのヘッダ情報はデータサイズがそれぞれ異なるので、どうしたらそれを分解できるかなと思った次第です。




ファイルから 4 バイト(32 ビット)単位で読み込む様にして、`read-byte` で読み出せばよろしいかと思います。

[code]

    (with-open-file (s "file" :direction :input :element-type '(unsigned-byte 32))
                    (read-byte s))
    
[/code]

`element-type` が `'(unsigned-byte 32)` の場合は `unsigned int`、 `'(signed-byte
32)` とすれば `signed int` として扱われる事になります。

例えば、以下の様にしてサンプルデータを作成して、

[code]

    $ perl -e "print pack('L', -10000)" > int.dat
    
[/code]

SBCL で読み込んでみます。

[code]

    * (with-open-file (s "int.dat" :direction :input :element-type '(signed-byte 32))
                      (read-byte s))
      => -10000
    
    * (with-open-file (s "int.dat" :direction :input :element-type '(unsigned-byte 32))
                      (read-byte s))
      => 4294957296
    
[/code]

**追記**

Quicklisp に [cl-binary-file](http://quickdocs.org/cl-binary-file/api) という
package がありました…。`signed/unsigned`, `little-endian/big-endian`
の指定ができるので、こちらの方が良いかもしれません。

[code]

    * (ql:quickload :cl-binary-file-0.4)
    * (use-package :binary-file)
    * (read-integer (open-binary-stream "int.dat") :bytes 4 :signed t :endianness :little-endian)
      => -10000
    * (read-integer (open-binary-stream "int.dat") :bytes 4 :signed nil :endianness :little-endian)
      => 4294957296
    
[/code]

※ SBCL では `sb-c:*backend-byte-order*` でシステムの byte order を取得できます。

[code]

    * sb-c:*backend-byte-order*
    
    :LITTLE-ENDIAN
    
[/code]

**追記その2**

> 同じファイルから4byteの整数以外にバイト列(unsigned-byte 8)も取得したい場合、element-
> typeを切り替えながら読み込むということは可能なのでしょうか？

はい、以下の様に `with-open-file` を2重にします。

[code]

    (with-open-file (s "int.dat" :direction :input :element-type 'unsigned-byte)
      (with-open-file (int32 "int.dat" :direction :input :element-type '(signed-byte 32))
                      (let ((x (make-array 4 :element-type 'unsigned-byte)))
                        (read-sequence x s)
                        (list x (read-byte int32)))))
    
    => (#(240 216 255 255) -10000)
    
[/code]




ファイルから 4 バイト(32 ビット)単位で読み込む様にして、`read-byte` で読み出せばよろしいかと思います。

[code]

    (with-open-file (s "file" :direction :input :element-type '(unsigned-byte 32))
                    (read-byte s))
    
[/code]

`element-type` が `'(unsigned-byte 32)` の場合は `unsigned int`、 `'(signed-byte
32)` とすれば `signed int` として扱われる事になります。

例えば、以下の様にしてサンプルデータを作成して、

[code]

    $ perl -e "print pack('L', -10000)" > int.dat
    
[/code]

SBCL で読み込んでみます。

[code]

    * (with-open-file (s "int.dat" :direction :input :element-type '(signed-byte 32))
                      (read-byte s))
      => -10000
    
    * (with-open-file (s "int.dat" :direction :input :element-type '(unsigned-byte 32))
                      (read-byte s))
      => 4294957296
    
[/code]

**追記**

Quicklisp に [cl-binary-file](http://quickdocs.org/cl-binary-file/api) という
package がありました…。`signed/unsigned`, `little-endian/big-endian`
の指定ができるので、こちらの方が良いかもしれません。

[code]

    * (ql:quickload :cl-binary-file-0.4)
    * (use-package :binary-file)
    * (read-integer (open-binary-stream "int.dat") :bytes 4 :signed t :endianness :little-endian)
      => -10000
    * (read-integer (open-binary-stream "int.dat") :bytes 4 :signed nil :endianness :little-endian)
      => 4294957296
    
[/code]

※ SBCL では `sb-c:*backend-byte-order*` でシステムの byte order を取得できます。

[code]

    * sb-c:*backend-byte-order*
    
    :LITTLE-ENDIAN
    
[/code]

**追記その2**

> 同じファイルから4byteの整数以外にバイト列(unsigned-byte 8)も取得したい場合、element-
> typeを切り替えながら読み込むということは可能なのでしょうか？

はい、以下の様に `with-open-file` を2重にします。

[code]

    (with-open-file (s "int.dat" :direction :input :element-type 'unsigned-byte)
      (with-open-file (int32 "int.dat" :direction :input :element-type '(signed-byte 32))
                      (let ((x (make-array 4 :element-type 'unsigned-byte)))
                        (read-sequence x s)
                        (list x (read-byte int32)))))
    
    => (#(240 216 255 255) -10000)
    
[/code]

