package io.loli.sc.server.redirect.file; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @author choco (loli@linux.com) */ public class FileCache implements Cache { private Path root; private static final Logger logger = LogManager.getLogger(FileCache.class); public FileCache() { } { init(); } /** * 初始化 */ private void init() { logger.info("初始化缓存"); root = new File(System.getProperty("java.io.tmpdir")).toPath(); try { if (!Files.exists(root)) Files.createDirectory(root); } catch (IOException e) { logger.error(e); throw new RuntimeException(e); } } /** * 将某个path的文件保存到文件缓存中 * * @param path 需要保存的文件path * @return 文件数组 */ @Override public byte[] saveFile(String path) { // 生成文件名 String fileName = path.substring(path.lastIndexOf("/") + 1); Path filePath = root.resolve(fileName); byte[] bytes = null; try (InputStream is = get(path).getValue();) { bytes = inputStreamToByte(is); Files.write(filePath, bytes); logger.info("将" + path + "写入文件系统"); // refreshCache(); } catch (IOException e) { logger.error(e); } return bytes; } /** * * <p> * 从缓存中获取指定path的文件 并将其保存至缓存中 <br> * 仅当文件缓存中不存在这个文件时 才从远端获取 * * <p> * 文件名是根据path自动取得的<br> * 如下<br> * http://1.loli.io/xxx.png to xxx<br> * http://1.loli.io/xxxx to xxxx * * @param path 需要获取的path * @return 如果存在 则返回该path 如果不存在 必须返回null */ public Path getFile(String path) { // 生成文件名 String fileName = path.substring(path.lastIndexOf("/") + 1); Path p = root.resolve(fileName); // 当该文件不存在时,就调用saveFile方法下载 if (!Files.exists(p)) { logger.info(path + "没有在缓存中找到"); if (!Files.exists(p)) { this.saveFile(path); } } else { logger.info("从缓存中找到" + path); } return p; } @Override public byte[] getBytes(String path) { // 生成文件名 String fileName = path.substring(path.lastIndexOf("/") + 1); Path p = root.resolve(fileName); byte[] bytes = null; // 当该文件不存在时,就调用saveFile方法下载 if (!Files.exists(p)) { logger.info(path + "没有在缓存中找到"); bytes = this.saveFile(path); } else { logger.info("从缓存中找到" + path); } // 再从文件系统中读取一次,不直接使用上面的数组 try (InputStream is = Files.newInputStream(p);) { bytes = inputStreamToByte(is); } catch (IOException e) { logger.error(e); } return bytes; } }