All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cc.owoo.godpen.network.http.cache.HttpLocalCache Maven / Gradle / Ivy

package cc.owoo.godpen.network.http.cache;

import cc.owoo.godpen.network.http.Response;
import cc.owoo.godpen.util.N;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

/**
 * HTTP本地缓存
 * Created by nimensei
 * 2022-11-11 下午 10:21
 */
public class HttpLocalCache {
    private static final HashMap localCacheFileMap = new HashMap<>();// 本地缓存
    private final Object lock = new Object();// 线程锁
    private LocalCacheFile localCacheFile;// 缓存文件
    private boolean isClose;// 是否已关闭

    private HttpLocalCache(LocalCacheFile localCacheFile) {
        this.localCacheFile = localCacheFile;
    }

    /**
     * 创建客户端缓存控制器
     *
     * @param rootPath 本地缓存路径
     */
    public static HttpLocalCache create(File rootPath) {
        if (rootPath == null)
            throw new NullPointerException("路径不能为空");
        String path = rootPath.getAbsolutePath();
        synchronized (localCacheFileMap) {
            LocalCacheFile localCacheFile = localCacheFileMap.get(path);
            if (localCacheFile == null) {
                localCacheFile = new LocalCacheFile(rootPath, path);
                try {
                    localCacheFile.reload();
                } catch (IOException ignored) {
                }
                localCacheFileMap.put(path, localCacheFile);
            }
            ++localCacheFile.quote;
            return new HttpLocalCache(localCacheFile);
        }
    }

    /**
     * 获取缓存路径
     *
     * @return 缓存路径
     */
    public File getCachePath() {
        return localCacheFile.getCachePath();
    }


    /**
     * 重新加载缓存
     */
    public void reload() {
        if (isClose)
            throw new NullPointerException("当前本地缓存已关闭");
        try {
            localCacheFile.reload();
        } catch (IOException ignored) {
        }
    }

    /**
     * 获取缓存文件
     *
     * @param url 文件URL
     * @return 缓存文件
     */
    public CacheFile get(String url) {
        if (isClose)
            throw new NullPointerException("当前本地缓存已关闭");
        if (url == null || (url = url.trim()).length() == 0)
            return null;
        String id = N.md5(url);
        CacheFile cacheFile;
        synchronized (localCacheFile.lock) {
            try {
                localCacheFile.checkCachePath();
            } catch (IOException e) {
                return null;
            }
            cacheFile = localCacheFile.get(id);
        }
        if (cacheFile != null)
            return cacheFile;
        File file = new File(getFilePath(id));
        if (!file.isFile())
            return null;
        try {
            cacheFile = CacheFile.create(file);
            return cacheFile;
        } catch (IOException e) {
            if (!file.delete())
                return null;
        }
        return null;
    }

    /**
     * 设置数据
     *
     * @param url      文件URL
     * @param response 响应数据
     * @param maxAge   最大缓存时间
     * @return 缓存文件
     */
    public CacheFile set(String url, Response response, int maxAge) throws IOException {
        if (isClose)
            throw new NullPointerException("当前本地缓存已关闭");
        if (url == null || (url = url.trim()).length() == 0)
            throw new NullPointerException("URL不能为空");
        if (response == null)
            throw new NullPointerException("响应数据不能为空");
        if (maxAge == 0)
            return null;
        if (maxAge < 0)
            throw new IllegalArgumentException("缓存时间不能小于0");
        String id = N.md5(url);
        File file = new File(getFilePath(id));
        CacheFile cacheFile;
        synchronized (localCacheFile.lock) {
            try {
                localCacheFile.checkCachePath();
            } catch (IOException e) {
                return null;
            }
            cacheFile = localCacheFile.computeIfAbsent(id, value ->
                    new CacheFile(file));
        }
        cacheFile.write(response, maxAge * 1000);
        return cacheFile;
    }

    /**
     * 删除文件
     *
     * @param url 文件URL
     * @throws IOException 删除失败
     */
    public void delete(String url) throws IOException {
        String id = N.md5(url);
        File file = new File(getFilePath(id));
        if (!file.delete())
            throw new IOException("文件删除失败:url = " + url + ", path = " + file.getAbsolutePath());
        localCacheFile.remove(id);
    }

    /**
     * 删除所有缓存文件
     *
     * @throws IOException 删除失败
     */
    public void deleteAll() throws IOException {
        synchronized (localCacheFile.lock) {
            String[] list = localCacheFile.rootFile.list();
            if (list == null)
                return;
            for (String name : list) {
                if (!name.endsWith(LocalCacheFile.FILE_POSTFIX))
                    continue;
                File file = new File(localCacheFile.rootPath + "/" + name);
                if (!file.isFile())
                    continue;
                if (!file.delete())
                    throw new IOException("文件删除失败:path = " + file.getAbsolutePath());
            }
            localCacheFile.clear();
        }
    }

    /**
     * 获取文件路径
     *
     * @param id 文件ID
     * @return 文件路径
     */
    private String getFilePath(String id) {
        return localCacheFile.rootPath + "/" + id + LocalCacheFile.FILE_POSTFIX;
    }

    /**
     * 关闭
     */
    public void close() {
        synchronized (lock) {
            if (isClose)
                return;
            isClose = true;
        }
        synchronized (localCacheFileMap) {
            if (--localCacheFile.quote == 0) {
                localCacheFileMap.remove(localCacheFile.rootPath);
                localCacheFile.clear();
            }
            localCacheFile = null;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy