Java tutorial
/* * Copyright (c) 2013, FPX and/or its affiliates. All rights reserved. Use, Copy is subject to authorized license. */ package info.donsun.cache.filecache; import info.donsun.cache.Cache; import info.donsun.cache.CacheException; import info.donsun.cache.filecache.config.CacheConfig; import info.donsun.core.utils.Values; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; /** * @author Steven Deng * @version 1.0 * @since 1.0 * @date 2013-10-9 * */ public class FileCache implements Cache { protected Logger log = Logger.getLogger(FileCache.class.getName()); private CacheConfig config; private static final Object LOCK = new Object(); /** * @param cache */ public FileCache(CacheConfig config) { this.config = config; } @Override public Object get(Object key) throws CacheException { synchronized (LOCK) { // if (exists(key)) { // ?? for (String fileName : listFileNames()) { if (isCacheFile(key, fileName)) { try { FileInputStream fileStream = new FileInputStream( FileUtils.getFile(config.getDir(), fileName)); ObjectInputStream in = new ObjectInputStream(fileStream); boolean isExpire = false; try { CachedObject cachedObject = (CachedObject) in.readObject(); // if (cachedObject.getExpire() > 0 && cachedObject.getExpire() < System.currentTimeMillis()) { isExpire = true; return null; } return cachedObject.getData(); } finally { in.close(); fileStream.close(); if (isExpire) { remove(key); } } } catch (Exception e) { throw new CacheException("Get cache file fail.", e); } } } } return null; } } @Override public void put(Object key, Object value) throws CacheException { synchronized (LOCK) { // ? remove(key); // id??? String fileName = formatId(key); // ttl<0?????? // File cacheDir = new File(config.getDir()); if (!cacheDir.exists() || !cacheDir.isDirectory()) { try { FileUtils.forceMkdir(cacheDir); } catch (IOException e) { throw new CacheException(String.format("Create cacheDir %s fail.", cacheDir.getPath())); } } // File file = FileUtils.getFile(config.getDir(), fileName); if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { throw new CacheException("Create new file " + file.getName() + " fail.", e); } } try { // ? FileOutputStream fileStream = new FileOutputStream(file); ObjectOutputStream out = new ObjectOutputStream(fileStream); try { CachedObject cachedObject = new CachedObject(); if (config.getExpireTime() != null) { cachedObject.setExpire(System.currentTimeMillis() + config.getExpireTime()); } cachedObject.setKey(key); cachedObject.setData(value); out.writeObject(cachedObject); } finally { out.close(); fileStream.close(); } } catch (Exception e) { throw new CacheException("Save cache file fail.", e); } } } @Override public List<Object> keys() throws CacheException { synchronized (LOCK) { List<Object> keys = new ArrayList<Object>(); for (String fileName : listFileNames()) { try { File file = FileUtils.getFile(config.getDir(), fileName); if (!file.exists()) { continue; } FileInputStream fileStream = new FileInputStream(file); ObjectInputStream in = new ObjectInputStream(fileStream); boolean isExpire = false; try { CachedObject cachedObject = (CachedObject) in.readObject(); // if (cachedObject.getExpire() > 0 && cachedObject.getExpire() < System.currentTimeMillis()) { isExpire = true; continue; } keys.add(cachedObject.getKey()); } finally { in.close(); fileStream.close(); if (isExpire) { FileUtils.forceDelete(file); } } } catch (Exception e) { throw new CacheException("Get cache file fail.", e); } } return keys; } } /** * ? * * @throws Exception * */ private boolean exists(Object key) { // ?? for (String fileName : listFileNames()) { if (isCacheFile(key, fileName)) { return true; } } return false; } /** * ?key * * @param key * @param fileName * @return */ private boolean isCacheFile(Object key, String fileName) { return fileName.toLowerCase().equals(formatId(key)); } /** * ???MD5?key * * @param key * @return */ private String formatId(Object key) { return DigestUtils.md5Hex(Values.getString(key).toLowerCase()); } private List<String> listFileNames() { String[] list = new File(config.getDir()).list(); List<String> files = new ArrayList<String>(); if (list != null && list.length > 0) { for (String file : list) { files.add(file); } } return files; } @Override public void remove(Object key) throws CacheException { synchronized (LOCK) { // ?? for (String fileName : listFileNames()) { if (isCacheFile(key, fileName)) { File file = FileUtils.getFile(config.getDir(), fileName); try { FileUtils.forceDelete(file); break; } catch (IOException e) { throw new CacheException("Delete file " + config.getDir() + " fail.", e); } } } } } @Override public void clear() throws CacheException { synchronized (LOCK) { File file = new File(config.getDir()); if (file.exists()) { try { FileUtils.cleanDirectory(file); } catch (IOException e) { throw new CacheException("Clean directory " + config.getDir() + " fail.", e); } } } } }