轻松实现本地缓存的创建,读取,删除

来源:互联网 发布:伴奏降调软件中文版 编辑:程序博客网 时间:2024/05/19 16:38
public class  ACache{   public static final int TIME_HOUR = 60 * 60;   public static final int TIME_DAY = TIME_HOUR * 24;   private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb   private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量   private static Map<String, ACache> mInstanceMap = new HashMap<String, ACache>();   private ACacheManager mCache;   public static ACache get(Context ctx) {      return get(ctx, "ACache");   }   public static ACache get(Context ctx, String cacheName) {      File f = new File(ctx.getCacheDir(), cacheName);      return get(f, MAX_SIZE, MAX_COUNT);   }   public static ACache get(File cacheDir) {      return get(cacheDir, MAX_SIZE, MAX_COUNT);   }   public static ACache get(Context ctx, long max_zise, int max_count) {      File f = new File(ctx.getCacheDir(), "ACache");      return get(f, max_zise, max_count);   }   public static ACache get(File cacheDir, long max_zise, int max_count) {      ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());      if (manager == null) {         manager = new ACache(cacheDir, max_zise, max_count);         mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);      }      return manager;   }   private static String myPid() {      return "_" + android.os.Process.myPid();   }   private ACache(File cacheDir, long max_size, int max_count) {      if (!cacheDir.exists() && !cacheDir.mkdirs()) {         throw new RuntimeException("can't make dirs in " + cacheDir.getAbsolutePath());      }      mCache = new ACacheManager(cacheDir, max_size, max_count);   }   class xFileOutputStream extends FileOutputStream {      File file;      public xFileOutputStream(File file) throws FileNotFoundException {         super(file);         this.file = file;      }      public void close() throws IOException {         super.close();         mCache.put(file);      }   }     /**    * 保存 String数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的String数据    */   public void put(String key, String value) {      File file = mCache.newFile(key);      BufferedWriter out = null;      try {         out = new BufferedWriter(new FileWriter(file), 1024);         out.write(value);      } catch (IOException e) {         e.printStackTrace();      } finally {         if (out != null) {            try {               out.flush();               out.close();            } catch (IOException e) {               e.printStackTrace();            }         }         mCache.put(file);      }   }   /**    * 保存 String数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的String数据    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, String value, int saveTime) {      put(key, Utils.newStringWithDateInfo(saveTime, value));   }   /**    * 读取 String数据    *     * @param key    * @return String 数据    */   public String getAsString(String key) {      File file = mCache.get(key);      if (!file.exists())         return null;      boolean removeFile = false;      BufferedReader in = null;      try {         in = new BufferedReader(new FileReader(file));         String readString = "";         String currentLine;         while ((currentLine = in.readLine()) != null) {            readString += currentLine;         }         if (!Utils.isDue(readString)) {            return Utils.clearDateInfo(readString);         } else {            removeFile = true;            return null;         }      } catch (IOException e) {         e.printStackTrace();         return null;      } finally {         if (in != null) {            try {               in.close();            } catch (IOException e) {               e.printStackTrace();            }         }         if (removeFile)            remove(key);      }   }     /**    * 保存 JSONObject数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的JSON数据    */   public void put(String key, JSONObject value) {      put(key, value.toString());   }   /**    * 保存 JSONObject数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的JSONObject数据    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, JSONObject value, int saveTime) {      put(key, value.toString(), saveTime);   }   /**    * 读取JSONObject数据    *     * @param key    * @return JSONObject数据    */   public JSONObject getAsJSONObject(String key) {      String JSONString = getAsString(key);      try {         JSONObject obj = new JSONObject(JSONString);         return obj;      } catch (Exception e) {         e.printStackTrace();         return null;      }   }      /**    * 保存 JSONArray数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的JSONArray数据    */   public void put(String key, JSONArray value) {      put(key, value.toString());   }   /**    * 保存 JSONArray数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的JSONArray数据    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, JSONArray value, int saveTime) {      put(key, value.toString(), saveTime);   }   /**    * 读取JSONArray数据    *     * @param key    * @return JSONArray数据    */   public JSONArray getAsJSONArray(String key) {      String JSONString = getAsString(key);      try {         JSONArray obj = new JSONArray(JSONString);         return obj;      } catch (Exception e) {         e.printStackTrace();         return null;      }   }     /**    * 保存 byte数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的数据    */   public void put(String key, byte[] value) {      File file = mCache.newFile(key);      FileOutputStream out = null;      try {         out = new FileOutputStream(file);         out.write(value);      } catch (Exception e) {         e.printStackTrace();      } finally {         if (out != null) {            try {               out.flush();               out.close();            } catch (IOException e) {               e.printStackTrace();            }         }         mCache.put(file);      }   }   /**    * Cache for a stream    *     * @param key    *            the file name.    * @return OutputStream stream for writing data.    * @throws FileNotFoundException    *             if the file can not be created.    */   public OutputStream put(String key) throws FileNotFoundException {      return new xFileOutputStream(mCache.newFile(key));   }   /**    *     * @param key    *            the file name.    * @return (InputStream or null) stream previously saved in cache.    * @throws FileNotFoundException    *             if the file can not be opened    */   public InputStream get(String key) throws FileNotFoundException {      File file = mCache.get(key);      if (!file.exists())         return null;      return new FileInputStream(file);   }   /**    * 保存 byte数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的数据    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, byte[] value, int saveTime) {      put(key, Utils.newByteArrayWithDateInfo(saveTime, value));   }   /**    * 获取 byte 数据    *     * @param key    * @return byte 数据    */   public byte[] getAsBinary(String key) {      RandomAccessFile RAFile = null;      boolean removeFile = false;      try {         File file = mCache.get(key);         if (!file.exists())            return null;         RAFile = new RandomAccessFile(file, "r");         byte[] byteArray = new byte[(int) RAFile.length()];         RAFile.read(byteArray);         if (!Utils.isDue(byteArray)) {            return Utils.clearDateInfo(byteArray);         } else {            removeFile = true;            return null;         }      } catch (Exception e) {         e.printStackTrace();         return null;      } finally {         if (RAFile != null) {            try {               RAFile.close();            } catch (IOException e) {               e.printStackTrace();            }         }         if (removeFile)            remove(key);      }   }     /**    * 保存 Serializable数据 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的value    */   public void put(String key, Serializable value) {      put(key, value, -1);   }   /**    * 保存 Serializable数据到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的value    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, Serializable value, int saveTime) {      ByteArrayOutputStream baos = null;      ObjectOutputStream oos = null;      try {         baos = new ByteArrayOutputStream();         oos = new ObjectOutputStream(baos);         oos.writeObject(value);         byte[] data = baos.toByteArray();         if (saveTime != -1) {            put(key, data, saveTime);         } else {            put(key, data);         }      } catch (Exception e) {         e.printStackTrace();      } finally {         try {            oos.close();         } catch (IOException e) {         }      }   }   /**    * 读取 Serializable数据     * @param key    * @return Serializable 数据    */   public Object getAsObject(String key) {      byte[] data = getAsBinary(key);      if (data != null) {         ByteArrayInputStream bais = null;         ObjectInputStream ois = null;         try {            bais = new ByteArrayInputStream(data);            ois = new ObjectInputStream(bais);            Object reObject = ois.readObject();            return reObject;         } catch (Exception e) {            e.printStackTrace();            return null;         } finally {            try {               if (bais != null)                  bais.close();            } catch (IOException e) {               e.printStackTrace();            }            try {               if (ois != null)                  ois.close();            } catch (IOException e) {               e.printStackTrace();            }         }      }      return null;   }    /**    * 保存 bitmap 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的bitmap数据    */   public void put(String key, Bitmap value) {      put(key, Utils.Bitmap2Bytes(value));   }   /**    * 保存 bitmap 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的 bitmap 数据    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, Bitmap value, int saveTime) {      put(key, Utils.Bitmap2Bytes(value), saveTime);   }   /**    * 读取 bitmap 数据    *     * @param key    * @return bitmap 数据    */   public Bitmap getAsBitmap(String key) {      if (getAsBinary(key) == null) {         return null;      }      return Utils.Bytes2Bimap(getAsBinary(key));   }      /**    * 保存 drawable 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的drawable数据    */   public void put(String key, Drawable value) {      put(key, Utils.drawable2Bitmap(value));   }   /**    * 保存 drawable 到 缓存中    *     * @param key    *            保存的key    * @param value    *            保存的 drawable 数据    * @param saveTime    *            保存的时间,单位:秒    */   public void put(String key, Drawable value, int saveTime) {      put(key, Utils.drawable2Bitmap(value), saveTime);   }   /**    * 读取 Drawable 数据    *     * @param key    * @return Drawable 数据    */   public Drawable getAsDrawable(String key) {      if (getAsBinary(key) == null) {         return null;      }      return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key)));   }   /**    * 获取缓存文件    *     * @param key    * @return value 缓存的文件    */   public File file(String key) {      File f = mCache.newFile(key);      if (f.exists())         return f;      return null;   }   /**    * 移除某个key    *     * @param key    * @return 是否移除成功    */   public boolean remove(String key) {      return mCache.remove(key);   }   /**    * 清除所有数据    */   public void clear() {      mCache.clear();   }   /**    * @title 缓存管理器    * @author 杨福海(michaelwww.yangfuhai.com    * @version 1.0    */   public class ACacheManager {      private final AtomicLong cacheSize;      private final AtomicInteger cacheCount;      private final long sizeLimit;      private final int countLimit;      private final Map<File, Long> lastUsageDates = Collections.synchronizedMap(new HashMap<File, Long>());      protected File cacheDir;      private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {         this.cacheDir = cacheDir;         this.sizeLimit = sizeLimit;         this.countLimit = countLimit;         cacheSize = new AtomicLong();         cacheCount = new AtomicInteger();         calculateCacheSizeAndCacheCount();      }      /**       * 计算 cacheSizecacheCount       */      private void calculateCacheSizeAndCacheCount() {         new Thread(new Runnable() {            @Override            public void run() {               int size = 0;               int count = 0;               File[] cachedFiles = cacheDir.listFiles();               if (cachedFiles != null) {                  for (File cachedFile : cachedFiles) {                     size += calculateSize(cachedFile);                     count += 1;                     lastUsageDates.put(cachedFile, cachedFile.lastModified());                  }                  cacheSize.set(size);                  cacheCount.set(count);               }            }         }).start();      }      private void put(File file) {         int curCacheCount = cacheCount.get();         while (curCacheCount + 1 > countLimit) {            long freedSize = removeNext();            cacheSize.addAndGet(-freedSize);            curCacheCount = cacheCount.addAndGet(-1);         }         cacheCount.addAndGet(1);         long valueSize = calculateSize(file);         long curCacheSize = cacheSize.get();         while (curCacheSize + valueSize > sizeLimit) {            long freedSize = removeNext();            curCacheSize = cacheSize.addAndGet(-freedSize);         }         cacheSize.addAndGet(valueSize);         Long currentTime = System.currentTimeMillis();         file.setLastModified(currentTime);         lastUsageDates.put(file, currentTime);      }      private File get(String key) {         File file = newFile(key);         Long currentTime = System.currentTimeMillis();         file.setLastModified(currentTime);         lastUsageDates.put(file, currentTime);         return file;      }      private File newFile(String key) {         return new File(cacheDir, key.hashCode() + "");      }      private boolean remove(String key) {         File image = get(key);         return image.delete();      }      private void clear() {         lastUsageDates.clear();         cacheSize.set(0);         File[] files = cacheDir.listFiles();         if (files != null) {            for (File f : files) {               f.delete();            }         }      }      /**       * 移除旧的文件       *        * @return       */      private long removeNext() {         if (lastUsageDates.isEmpty()) {            return 0;         }         Long oldestUsage = null;         File mostLongUsedFile = null;         Set<Entry<File, Long>> entries = lastUsageDates.entrySet();         synchronized (lastUsageDates) {            for (Entry<File, Long> entry : entries) {               if (mostLongUsedFile == null) {                  mostLongUsedFile = entry.getKey();                  oldestUsage = entry.getValue();               } else {                  Long lastValueUsage = entry.getValue();                  if (lastValueUsage < oldestUsage) {                     oldestUsage = lastValueUsage;                     mostLongUsedFile = entry.getKey();                  }               }            }         }         long fileSize = calculateSize(mostLongUsedFile);         if (mostLongUsedFile.delete()) {            lastUsageDates.remove(mostLongUsedFile);         }         return fileSize;      }      private long calculateSize(File file) {         return file.length();      }   }   /**    * @title 时间计算工具类    * @version 1.0    */   private static class Utils {      /**       * 判断缓存的String数据是否到期       *        * @param str       * @return true:到期了 false:还没有到期       */      private static boolean isDue(String str) {         return isDue(str.getBytes());      }      /**       * 判断缓存的byte数据是否到期       *        * @param data       * @return true:到期了 false:还没有到期       */      private static boolean isDue(byte[] data) {         String[] strs = getDateInfoFromDate(data);         if (strs != null && strs.length == 2) {            String saveTimeStr = strs[0];            while (saveTimeStr.startsWith("0")) {               saveTimeStr = saveTimeStr.substring(1, saveTimeStr.length());            }            long saveTime = Long.valueOf(saveTimeStr);            long deleteAfter = Long.valueOf(strs[1]);            if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {               return true;            }         }         return false;      }      private static String newStringWithDateInfo(int second, String strInfo) {         return createDateInfo(second) + strInfo;      }      private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) {         byte[] data1 = createDateInfo(second).getBytes();         byte[] retdata = new byte[data1.length + data2.length];         System.arraycopy(data1, 0, retdata, 0, data1.length);         System.arraycopy(data2, 0, retdata, data1.length, data2.length);         return retdata;      }      private static String clearDateInfo(String strInfo) {         if (strInfo != null && hasDateInfo(strInfo.getBytes())) {            strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1, strInfo.length());         }         return strInfo;      }      private static byte[] clearDateInfo(byte[] data) {         if (hasDateInfo(data)) {            return copyOfRange(data, indexOf(data, mSeparator) + 1, data.length);         }         return data;      }      private static boolean hasDateInfo(byte[] data) {         return data != null && data.length > 15 && data[13] == '-' && indexOf(data, mSeparator) > 14;      }      private static String[] getDateInfoFromDate(byte[] data) {         if (hasDateInfo(data)) {            String saveDate = new String(copyOfRange(data, 0, 13));            String deleteAfter = new String(copyOfRange(data, 14, indexOf(data, mSeparator)));            return new String[] { saveDate, deleteAfter };         }         return null;      }      private static int indexOf(byte[] data, char c) {         for (int i = 0; i < data.length; i++) {            if (data[i] == c) {               return i;            }         }         return -1;      }      private static byte[] copyOfRange(byte[] original, int from, int to) {         int newLength = to - from;         if (newLength < 0)            throw new IllegalArgumentException(from + " > " + to);         byte[] copy = new byte[newLength];         System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));         return copy;      }      private static final char mSeparator = ' ';      private static String createDateInfo(int second) {         String currentTime = System.currentTimeMillis() + "";         while (currentTime.length() < 13) {            currentTime = "0" + currentTime;         }         return currentTime + "-" + second + mSeparator;      }      /*       * Bitmap → byte[]       */      private static byte[] Bitmap2Bytes(Bitmap bm) {         if (bm == null) {            return null;         }         ByteArrayOutputStream baos = new ByteArrayOutputStream();         bm.compress(Bitmap.CompressFormat.PNG, 100, baos);         return baos.toByteArray();      }      /*       * byte[] → Bitmap       */      private static Bitmap Bytes2Bimap(byte[] b) {         if (b.length == 0) {            return null;         }         return BitmapFactory.decodeByteArray(b, 0, b.length);      }      /*       * Drawable → Bitmap       */      private static Bitmap drawable2Bitmap(Drawable drawable) {         if (drawable == null) {            return null;         }         //  drawable 的长宽         int w = drawable.getIntrinsicWidth();         int h = drawable.getIntrinsicHeight();         //  drawable 的颜色格式         Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;         // 建立对应 bitmap         Bitmap bitmap = Bitmap.createBitmap(w, h, config);         // 建立对应 bitmap 的画布         Canvas canvas = new Canvas(bitmap);         drawable.setBounds(0, 0, w, h);         //  drawable 内容画到画布中         drawable.draw(canvas);         return bitmap;      }      /*       * Bitmap → Drawable       */      @SuppressWarnings("deprecation")      private static Drawable bitmap2Drawable(Bitmap bm) {         if (bm == null) {            return null;         }         BitmapDrawable bd=new BitmapDrawable(bm);         bd.setTargetDensity(bm.getDensity());         return new BitmapDrawable(bm);      }   }}
原创粉丝点击