ビューアと言いつつ、エクスプローラのような一覧表示画面もあるので、画像ファイルのサムネイルも生成しています。
一度読み込んだファイルは以後高速に表示するために、キャッシュする仕組みを導入しています。
アプリケーション内では以下のようにキャッシュデータを生成しています。
- 画像ファイルを読み込む。
- サムネイル用にリサイズ。
- WEBP形式のバイト配列に圧縮。
そして元々は以下のようにキャッシュファイルに保存していました。
- キャッシュファイルに追記
- データベースにキャッシュファイル内の位置とサイズを保存。
- キャッシュファイルサイズが上限を超えたらキャッシュファイルを削除、データベースをリセット。
問題点
- キャッシュファイルからデータを取得するために、先頭からシークする必要がある。
- キャッシュファイルを分割すればシークするサイズを減らせるが、それでも同じ問題は付きまとう。さらに対象のファイルを検索するという処理も必要になる。
そこでMemoryMappedFileというクラスを知りました。
- キャッシュファイル内をランダムアクセスできる。
- OSの仮想メモリ管理機能を利用できる。
- 一度読み込んだ領域は以後、アクセス頻度やメモリの空き状況に基づいてメモリに保持する。
大雑把な言い方をすると、ランダムアクセスできて、一度アクセスした領域はメモリに保持し続け、最大でキャッシュファイルのサイズ分のメモリを使用する、ということです。
これにより以下のようになりました。
- 空のキャッシュファイルを最大サイズで作成。
- キャッシュファイルに書き込み。
- データベースにキャッシュファイル内の位置とサイズを保存。
- キャッシュが上限を超えたらデータベースをリセット。
繰り返しになりますが、一度読み込んだ領域はOS任せでメモリに保持し続けるわけですが、私のアプリケーションではキャッシュファイルのサイズを100MBとし、最大で100MBのメモリを使用することを許容できたのでこれを採用しました。
キャッシュファイルを使用する際の方法の一つとして知っていただければ幸いです。