DiskBasedCache中定义了一个CacheHeader内部类,表示缓存信息的摘要,存储在缓存文件的头部,网络请求的缓存写入与读取都是通过CacheHeadler类来操作的。与Cache接口的内部类Cache.Entry相似。
CacheHeader的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| static class CacheHeader { /**缓存文件的大小 */ public long size;
/**缓存文件的key,也就是url */ public String key;
/** 用于缓存新鲜度验证的 ETag */ public String etag;
/** 缓存产生的时间 */ public long serverDate;
/** 缓存文件在服务器端最后的修改时间 */ public long lastModified;
/** 缓存过期时间*/ public long ttl;
/** 缓存的新鲜度时间 */ public long softTtl;
/** 缓存对应的首部信息 */ public Map<String, String> responseHeaders;
private CacheHeader() { } public CacheHeader(String key, Entry entry) { this.key = key; this.size = entry.data.length; this.etag = entry.etag; this.serverDate = entry.serverDate; this.lastModified = entry.lastModified; this.ttl = entry.ttl; this.softTtl = entry.softTtl; this.responseHeaders = entry.responseHeaders; }
public static CacheHeader readHeader(InputStream is) throws IOException { CacheHeader entry = new CacheHeader(); int magic = readInt(is); if (magic != CACHE_MAGIC) { // don't bother deleting, it'll get pruned eventually throw new IOException(); } entry.key = readString(is); entry.etag = readString(is); if (entry.etag.equals("")) { entry.etag = null; } entry.serverDate = readLong(is); entry.lastModified = readLong(is); entry.ttl = readLong(is); entry.softTtl = readLong(is); entry.responseHeaders = readStringStringMap(is);
return entry; }
public Entry toCacheEntry(byte[] data) { Entry e = new Entry(); e.data = data; e.etag = etag; e.serverDate = serverDate; e.lastModified = lastModified; e.ttl = ttl; e.softTtl = softTtl; e.responseHeaders = responseHeaders; return e; }
public boolean writeHeader(OutputStream os) { try { writeInt(os, CACHE_MAGIC); writeString(os, key); writeString(os, etag == null ? "" : etag); writeLong(os, serverDate); writeLong(os, lastModified); writeLong(os, ttl); writeLong(os, softTtl); writeStringStringMap(responseHeaders, os); os.flush(); return true; } catch (IOException e) { VolleyLog.d("%s", e.toString()); return false; } }
}
|
readHeader(InputStream is)读头信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public static CacheHeader readHeader(InputStream is) throws IOException { CacheHeader entry = new CacheHeader(); int magic = readInt(is); if (magic != CACHE_MAGIC) { // don't bother deleting, it'll get pruned eventually throw new IOException(); } entry.key = readString(is); entry.etag = readString(is); if (entry.etag.equals("")) { entry.etag = null; } entry.serverDate = readLong(is); entry.lastModified = readLong(is); entry.ttl = readLong(is); entry.softTtl = readLong(is); entry.responseHeaders = readStringStringMap(is);
return entry; }
|
在方法体的第三行,验证输入流对应的缓存文件的合法性。如果读出的magic不等于写入的magic,终止读写,如果合法,从缓存文件中读出结构数据,组成对象返回。
writeHeader(OutputStream os)与上面方法相反,这里将maic和一些属性信息写入到缓存文件。注意写文件也是按照结构来写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public boolean writeHeader(OutputStream os) { try { writeInt(os, CACHE_MAGIC); writeString(os, key); writeString(os, etag == null ? "" : etag); writeLong(os, serverDate); writeLong(os, lastModified); writeLong(os, ttl); writeLong(os, softTtl); writeStringStringMap(responseHeaders, os); os.flush(); return true; } catch (IOException e) { VolleyLog.d("%s", e.toString()); return false; } }
|
toCacheEntry(byte[] data)方法,此方法用于将头信息和数据信息封装成Entry(Cache的单位数据)返回,代码很简单。
1 2 3 4 5 6 7 8 9 10 11
| public Entry toCacheEntry(byte[] data) { Entry e = new Entry(); e.data = data; e.etag = etag; e.serverDate = serverDate; e.lastModified = lastModified; e.ttl = ttl; e.softTtl = softTtl; e.responseHeaders = responseHeaders; return e; }
|
readInt 和writeInt
readLong和 writeLong
readString和writeString
readStringStringMap和writeStringStringMap
这些方法是DiskBasedCache中定义的方法,主要用于头信息读写有结构的数据,其中夹杂着一些自定义的位运算,这部分的源码没看懂。
Volley的cache之硬盘缓存–DiskBasedCache(作者的其他博文也值得学习)
Volley源码解读
上一篇:Volley的硬盘缓存--Cache,DiskBasedCache,NoCache的源码分析
下一篇:Volley-Network及其实现类的源码解析