netail.net
自作フリーソフトや,ゲームに関する雑記を公開してます.
日記はソフトウェア工学の論文ネタが中心です.
最近のお知らせ (古いものはこちら)
2008-04-25 [長年日記] ▲
_ [Java] ファイルの一部だけ読む Reader ▲
既存のファイル処理コードに対して,手持ちファイルの一部だけをさも独立したファイルであるかのように読ませたかったので,あやしい Readerクラスを作成してみました.
このオブジェクトは,引数として与えられた Reader から,引数 pBegin バイト目から pEnd-1 バイト目までを読みます.long 値のオーバーフロー対策以外には特に工夫はありません.「読みすぎた分は単に捨てる」方式なので,元となった Reader が pEnd バイト目から続きを読めることも保証しません.
public class FileRangeReader extends Reader { private Reader r; private long size; // どこまで読むか private long offset; // どこまで読んだか public FileRangeReader(Reader reader, long pBegin, long pEnd) throws IOException { r = reader; r.skip(pBegin); size = pEnd - pBegin; offset = 0; } @Override public void close() throws IOException { r.close(); } @Override public int read(char[] buf, int off, int len) throws IOException { if (size == offset) return -1; int bytes = r.read(buf, off, len); if (offset > size - bytes) { // == offset + bytes > size. bytes = (int)(size - offset); } offset += bytes; return bytes; } }
2個以上のReaderの中身をさも連続したストリームであるかのように読み込むReaderなんかも,上記のコードと同様に簡単に作成できるので,Decorator パターンはやっぱり強力だなと思います.良い設計かどうかはともかく,既存コードの変更量がとにかく少ない,というのがありがたいところです.
(追記: 2008/9/8) Reader は char 配列を読み込むため,ストリームのデータの中身を確認する必要があり,大量のデータを読み飛ばすには問題があるようです.InputStream をベースに同様のコードを作れば,byte単位で処理できるので,かなり高速になります.