iText の PdfReader クラスで RandomAccessFileOrArray オブジェクトを引数に取るコンストラクタは廃止予定 (Deprecated)

iText (iTextSharp) でファイルサイズの大きな PDF を扱う場合、メモリや速度の問題を解決するために RandamAccessFileOrArray クラスを利用すると言う方法が存在します。

対策方法はないかと調べたところ、PdfReader クラスのコンストラクター

public PdfReader(RandomAccessFileOrArray raf, byte ownerPassword[])

を利用すればよいことが分かりました。このコンストラクターを使用して PdfReader インスタンスを生成すると、PdfReader は pertial mode というモードで動作します。このモードでは、全体を読み込まずに、必要なページを部分的に読み込みます。

iText で大量の PDF をマージする - 倖せの迷う森

私もこれまで PdfReader クラスを利用する際はこの方法を用いていたのですが、先日、iTextSharp のバージョンを 5.4.3 に上げたところ、以下のように Obsolete (Deprecated) の警告が出るようになりました。

警告 'iTextSharp.text.pdf.PdfReader.PdfReader(iTextSharp.text.pdf.RandomAccessFileOrArray, byte[])' は古い形式です: 'Use the constructor that takes a RandomAccessFileOrArray'

iText の API リファレンス を見ても確かに Deprecated となっているようです。リファレンスには「代わりに RandomAccessSource を利用するコンストラクタを使え」と書いてあるのですが、API リファレンス自体には RandomAccessSource を引数に取るようなコンストラクタは掲載されていないし、どれを使えば良いんだ……?としばらく悩む事になりました。

結論から言うと、代替手段としては下記のコンストラクタで第 3 引数を true にして使用すると良いようです(このコンストラクタは、ver. 5.4.3 で追加された模様)。

PdfReader(String filename, byte[] ownerPassword, boolean partial) 

iTextSharp のソースコードを見ると、上記のコンストラクタは内部で RandomAccessSourceFactory クラス経由で適切な RandomAccessSource オブジェクトを生成しており、第 3 引数を true にすると、このオブジェクトを利用して pertial mode で PDF ファイルへアクセスするようです。

public PdfReader(String filename, byte[] ownerPassword, bool partial) : this(
    new RandomAccessSourceFactory()
    .SetForceRead(false)
    .CreateBestSource(filename),
    partial,
    ownerPassword,
    null,
    null,
    true) {
}

そんな訳で「Deprecated はいいけど代替手段はどれなんだよ!」と悩んだお話でした。