IT@程序员猿媛

Android - DiskLruCache 文件缓存

2019-04-14  本文已影响17人  拾识物者

什么是 DiskLruCache

是文件缓存的管理对象,使用 LRU 算法对保存在永久存储设备上的缓存文件进行管理。

比手机的闪存更低速的访问设备是网络,文件缓存的意义就在于通过重复利用缓存的数据,减少网络请求,减少网络流量,提高响应速度。

用法

  1. 使用静态方法 static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) 来创建 DiskLruCache 对象。
    1. 构造方法是 private 修饰的,无法使用。
    2. 参数 directory 表示保存的目录,注意外部目录权限问题
    3. 参数 appVersion 可以设置为版本号 version code。
    4. 参数 valueCount 表示一个 key 可以关联几个文件,一般为 1(一般情况关联多个没有必要,而且会增加编码复杂度)
    5. 参数 maxSize 缓存大小限制,单位 Byte。
    6. 需要调用 close() 关闭,见 [4.]
  2. 读取缓存
    1. 先调用 DiskLruCache.Snapshot get(String key) 获取一个 DiskLruCache.Snapshot 对象,再通过这个对象进行读取操作。
    2. 返回的类型是 DiskLruCache.Snapshot,其实就是这个 key 对应的相关数据,主要是多个文件的输入流和大小,多个文件的数量对应构造方法里的 valueCount
    3. Snapshot.getLength(int index) 获取文件大小,进行一些判断。
    4. Snapshot.getInputStream(int index) 获取一个 InputStream,可以用来读取文件内容,注意这个流不是缓存流,如果需要缓存流可以创建 BufferedInputStream 包装一下 InputStream
    5. 这个 InputStream 需要手动关闭,既可以直接关闭 InputStream,也可以调用 Snapshot.close() 来关闭属于它的所有 InputStream
  3. 写入缓存
    1. 先调用 DiskLruCache.Editor edit(String key) 方法获取一个 DiskLruCache.Editor 对象,再通过这个对象进行写入操作。
    2. 返回的类型是 DiskLruCache.Editor,其实就是将写入相关的一些操作抽象处理,对这个对象的操作都对应 key 关联的缓存文件。
    3. 如果同时有另一个 Editor 对象是通过 key 获取的,edit 方法将返回 null。保证同时只有一个 Editor 对象在对同一个 key 进行写入操作。因此调用之后需要判断一下。
    4. OutputStream newOutputStream(int index) 创建输出流来写入数据,注意这个流不是缓存流,如果需要缓存流可以创建 BufferedOutputStream 包装一下 OutputStream
    5. 这个 OutputStream 需要手动关闭。
    6. 除了关闭输出流,还还需对 Editor 设置结果。如果写入操作和相关业务成功了,缓存文件有效,则调用 Editor.commit() 方法表示缓存写入成功。如果写入操作或相关业务失败了,缓存文件无效,则调用 Editor.abort() 来还原为未获取 Editor 之前的状态。

线程安全和一致性

注意

实现原理

DiskLruCache 内部使用一个 journal 文件来记录和管理缓存文件。文件内容大概长这样:

libcore.io.DiskLruCache
1
100
2

CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
DIRTY 335c4c6028171cfddfbaae1a9c313c52
CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
REMOVE 335c4c6028171cfddfbaae1a9c313c52
DIRTY 1ab96a171faeeee38496d8b330771a7a
CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
READ 335c4c6028171cfddfbaae1a9c313c52
READ 3400330d1dfc7f3f7f4b8d4d803dfcf6

journal 文件记录了一些元信息,比如版本号什么的。

journal 文件还记录了每个 Entry 的数据,有四种状态:

Entry 数据并不是在记录的位置“原地”修改,而是不停地添加新的状态到文件末尾,只有读取到最新的一条 Entry 相关的记录才能知道它的最新状态。随着操作越来越多,DiskLruCache 也会执行压缩,删除之前的状态。

(ole)

上一篇下一篇

猜你喜欢

热点阅读