バイナリファイルというと、テキストファイルと異なり、実際のデータ構造が見えにくいせいか、なにか特殊なものと敬遠されることが多いようです。しかし、バイナリファイルも、要は「byte型のデータの連なり」であるにすぎません。
テキストファイルを文字、あるいは行という単位で読み書きしたのと同様、バイナリファイルを読み書きする場合にはbyte値の単位でデータを処理する、それだけのことです。
ここでは、バイナリファイル入出力の最も基本的な例として、サーバ上にある画像データ(JPEG画像)を読み込み、ブラウザにそのまま出力してみましょう。もちろん、バイナリファイルを直接に出力するだけであるならば、クライアントからアクセス可能なディレクトリにファイルを配置してもよいかもしれません。しかし、バイナリファイル個々に対してアクセスの可否を制御したい場合やアクセス(ダウンロード)状況を監視したいなどといった場合には、このようなスクリプトを間に介することで容易に制御ができます。
以下のdisplayImage.jspは、指定されたJPEG画像を読み込み、そのままブラウザに出力するためのJSPファイルです。JPEG画像の指定は、クエリ情報を介して行うものとします。
<%@ page contentType="image/jpeg" import="java.io.*" %> <% final String IMAGE_PATH="C:\\image"; File objFle=new File(IMAGE_PATH,request.getParameter("image")); if(objFle.getParent().equals(IMAGE_PATH)){ FileInputStream objFis=new FileInputStream(objFle); ServletOutputStream objSos=response.getOutputStream(); int i; while((i=objFis.read())!=-1){objSos.write(i);} objSos.close(); } else { response.sendError(HttpServletResponse.SC_FORBIDDEN); } %>
このコードの実行結果は以下のようになります。
こうしてみると、バイナリファイル入出力の処理が実にシンプルであることがお分かりになるのではないでしょうか。FileInputStream#readメソッドが-1を返すまで(ファイルの終端に到達するまで)順にバイトデータを読み込んでいき、ServletOutputStream#writeメソッドでそのまま出力する――ただそれだけのことです。ServletOutputStreamクラスは、書き込まれたデータをブラウザに対してそのまま(文字列変換などの処理を介することなく)生のバイトデータとして出力するためのクラスです。
なお、本例ではファイルの読み込みに際して、あらかじめパスを限定し、なおかつFile#getParentメソッドで最終的に生成されたパスが、もともと参照を許されたディレクトリ直下のものであるかどうかを確認しています。もしもクエリ情報から自由にルートからのパスを設定できるようにしてしまった場合、サーバ内のファイルを自由に読み取られてしまう危険性もありますので、くれぐれも注意してください。
Copyright © ITmedia, Inc. All Rights Reserved.