RubyでBase64

Rubyでファイルアップローダおよびダウンローダを作った。ブラウザからファイルを投稿して、DBに保存して、あとでダウンロードできるやつ。

ファイル実体をファイルシステムに保存するのではなく、DBに入れる。Webから見える領域に置いてそのままダウンロードしたり、Webから見えない領域に置いてプログラム経由でダウンロードさせる方式は、簡単そうに見えて、罠が多い。DBに入れてプログラム経由でダウンロードさせるのが結果的に一番簡単だと思う。

通常バイナリデータをDBに入れるときははBLOB型のカラムを使うと思うけど、今回はRuby/MySQLを使っていることもあり (PreparedStatementが使えない)、文字列だけのSQLでやる必要がある。

そこで、バイナリデータをBase64エンコードし、LONGTEXT型のカラムに入れることにした。もちろん、ダウンロードの際は取り出したテキストデータをBase64デコードしてからクライアントに返す。

Base64エンコード/デコード

RubyにはBase64ライブラリが付属してるけど、どうやら実装サンプルのような位置づけで、本気で使うためのものでは無いっぽい (ってことで合ってる?)。

その代わり、Array#packメソッドでBase64エンコード、String#unpackメソッドでBase64デコードができる。

実装例

ファイルアップロード時など、バイナリデータをBase64エンコードする場合は以下。

base64_text = [binary_data].pack('m')

ファイルダウンロード時など、Base64エンコードされたテキストデータをバイナリデータへデコードする場合は以下。

binary_data = base64_text.unpack('m')[0]

簡単。だけど知らないと絶対書けない気がする。

とりあえず、このやり方で無事ファイルアップローダおよびダウンローダを作った。