1. 画面表示
  2. ファイル出力


Ruby バイナリデータの処理関係

画面表示

  • printf

  • a = 15
    printf("%d => 0x%02x\n", a, a)    #=>  "15 => 0x0f"

ファイル出力

ファイルにバイナリデータとして書き込みたい場合、Array.packを使用する方法があります。

  • Array.pack('c*'): char (8bit 符号付き整数)
  • Array.pack('C*'): unsigned char (8bit 符号なし整数)
  • Array.pack('s*'): short (16bit 符号付き整数, エンディアン依存)
  • Array.pack('S*'): unsigned short (16bit 符号なし整数, エンディアン依存)
  • Array.pack('l*'): long (32bit 符号付き整数, エンディアン依存)
  • Array.pack('L*'): unsigned long (32bit 符号なし整数, エンディアン依存)
  • Array.pack('q*'): long long (64bit 符号付き整数, エンディアン依存)
  • Array.pack('Q*'): unsigned long long (64bit 符号なし整数, エンディアン依存)
  • Array.pack('m'): base64された文字列。60オクテッドごとと最後に改行コードが付加

  • バイト単位の出力

  • ファイルにバイト単位でバイナリデータを書き込みたい場合, 以下のようにします。 基本的にはArray.packに、大文字の"C"(8bit 符号無し整数)を指定して使用します。

    #  205 = 0xCD, 216 = 0xD8, 255 = 0xFF
    data = [205, 216, 0, 255]    # 10進数の配列
    
    f = open('tmp.bin', 'wb')
    f.write(data.pack('C*'))     # 出力は16進数で CD D8 00 FF
    f.close
    これは以下のようにもできます。
    #  205 = 0xCD, 216 = 0xD8, 255 = 0xFF
    data = [205, 216, 0, 255]    # 10進数の配列
    
    f = open('tmp.bin', 'wb')
    data.each do |d|             
      f.write([d].pack('C'))     # 出力は16進数で CD D8 00 FF
    end
    
    f.close			

    間違った例

    # 205 = 0xCD, 216 = 0xD8, 255 = 0xFF
    data = [205, 216, 0, 255]
    
    f = open('tmp.bin', 'wb')
    f.write(data.pack('C'))      # 出力は16進数で  CD
    f.close			
    これを実行すると、ファイルtmp.bin の中身は、0xCDのみになります。 Array.pack('C') は配列の1つ目のみを処理するので、205以外が無視されます。 data.pack('L')の場合(32ビット符号なしへの変換)、ファイルのバイナリデータは 0xCD, 0, 0, 0 のファイルになります。

  • base64

  • base64された文字列を出力したい場合は、Array.packで、"m"を指定します。

    data = ["1234ABCD"]
    f = open('tmp_base64.bin', 'wb')
    f.write(data.pack('m'))           # 出力ファイルの中身 "MTIzNEFCQ0Q="
    f.close			

    間違った例1

    data = ["1", "2", "3", "4", "A", "B", "C", "D" ]
    				
    f = open('tmp_base64_miss.txt', 'wb')
    
    f.write(data.pack('m'))           # 出力ファイルの中身 "MQ==" 
    
    f.close			
    この出力は、data = ["1"] をbase64 で変換した結果の "MQ==" と同じで、 配列の1つ目だけを変換したものになります。

    間違った例2

    data = [205, 216, 0, 255]
    
    f = open('tmp_base64_miss2.txt', 'wb')
    
    f.write(data.pack('m'))
    
    f.close			
    これを実行すると、以下のようなエラーになります。
    binary.rb:29:in `pack': can't convert Fixnum into String (TypeError)
            from binary.rb:29