DiskLruCache 本地文件缓存

大家都知道文件的保存和读取是如何使用,少量的文件可以通过获取文件名来读取文件,但是对于大批量下载的临时文件都是不规则存储的,如何保存和获取各个文件的信息,那接下来我们就来讲下如何通过DiskLruCache工具类来处理这些事情。

首先需要初始化工具类:很简单一句话:

mDiskCache = DiskLruCache.open(file,1,1,1024*1024*16/8,100);
复制代码

分析一下这个方法: 首先新建了一个Journal.tmp临时文件,再把临时文件重命名为Journal,该文件用于存储所以缓存的文件信息key和count等。

public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize, int maxFileCount)
        throws IOException {
    ...省略了
    cache = new DiskLruCache(directory, appVersion, valueCount, maxSize, maxFileCount);
    cache.rebuildJournal();
    return cache;
}

private synchronized void rebuildJournal() throws IOException {
    ...
    Writer writer = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(journalFileTmp), Util.US_ASCII));
    ...略
    if (journalFile.exists()) {
        renameTo(journalFile, journalFileBackup, true);
    }
    renameTo(journalFileTmp, journalFile, false);
    journalFileBackup.delete();

    journalWriter = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(journalFile, true), Util.US_ASCII));
}
复制代码

存储文件:获取Editor,得到一个Ops,给Ops赋值,然后调用commit方法实现写文件和写存储的文件信息。

    DiskLruCache.Editor editor = mDiskCache.edit(generateKey(url));
    if(editor != null){
        OutputStream outputStream = editor.newOutputStream(0);
        downLoadFile(url,outputStream);
        editor.commit();
    }
复制代码

接下来重点来看下工具类的get方法,即读文件。观源码可知,通过Entry entry = lruEntries.get(key);最后获取一个Snapshot对象。通过该对象获取文件信息。

public synchronized Snapshot get(String key) throws IOException {
    checkNotClosed();
    validateKey(key);
    Entry entry = lruEntries.get(key);
    if (entry == null) {
        return null;
    }

    if (!entry.readable) {
        return null;
    }

    // Open all streams eagerly to guarantee that we see a single published
    // snapshot. If we opened streams lazily then the streams could come
    // from different edits.
    File[] files = new File[valueCount];
    InputStream[] ins = new InputStream[valueCount];
    try {
        File file;
        for (int i = 0; i < valueCount; i++) {
            file = entry.getCleanFile(i);
            files[i] = file;
            ins[i] = new FileInputStream(file);
        }
    } catch (FileNotFoundException e) {
        // A file must have been deleted manually!
        for (int i = 0; i < valueCount; i++) {
            if (ins[i] != null) {
                Util.closeQuietly(ins[i]);
            } else {
                break;
            }
        }
        return null;
    }

    redundantOpCount++;
    journalWriter.append(READ + ' ' + key + '\n');
    if (journalRebuildRequired()) {
        如果文件超过最大存储数,会优先除去不经常使用的文件。
        executorService.submit(cleanupCallable);
    }

    return new Snapshot(key, entry.sequenceNumber, files, ins, entry.lengths);
}
复制代码

转载于:https://juejin.im/post/5cd0f184f265da037d4fc138

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值