package com.jerey.lruCache;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import static com.jerey.lruCache.DiskLruCache.TAG;
/**
* Created by xiamin on 3/4/17.
*/
public class DiskLruCacheManager {
private static final String DEFAULT_DIR_NAME = "diskCache";
private static final int MAX_COUNT = 10 * 1024 * 1024;
private static final int DEFAULT_APP_VERSION = 1;
private static final int DEFAULT_VALUE_COUNT = 1;
private static DiskLruCache mDiskLruCache = null;
public DiskLruCacheManager(Context context) throws IOException {
this(context, DEFAULT_DIR_NAME, MAX_COUNT);
}
public DiskLruCacheManager(Context context, String dirName) throws IOException {
this(context, dirName, MAX_COUNT);
}
public DiskLruCacheManager(Context context, String dirName, int maxCount) throws IOException {
mDiskLruCache = generateCache(context, dirName, maxCount);
}
//custom cache dir
public DiskLruCacheManager(File dir) throws IOException {
this(null, dir, MAX_COUNT);
}
public DiskLruCacheManager(Context context, File dir) throws IOException {
this(context, dir, MAX_COUNT);
}
public DiskLruCacheManager(Context context, File dir, int maxCount) throws IOException {
mDiskLruCache = generateCache(context, dir, maxCount);
}
private DiskLruCache generateCache(Context context, String dirName, int maxCount) throws IOException {
DiskLruCache diskLruCache = DiskLruCache.open(
getDiskCacheDir(context, dirName),
Utils.getAppVersion(context),
DEFAULT_VALUE_COUNT,
maxCount);
return diskLruCache;
}
private DiskLruCache generateCache(Context context, File dir, int maxCount) throws IOException {
if (!dir.exists() || !dir.isDirectory()) {
throw new IllegalArgumentException(
dir + " is not a directory or does not exists. ");
}
int appVersion = context == null ? DEFAULT_APP_VERSION : Utils.getAppVersion(context);
DiskLruCache diskLruCache = DiskLruCache.open(
dir,
appVersion,
DEFAULT_VALUE_COUNT,
maxCount);
return diskLruCache;
}
/**
* 获取缓存的路径 两个路径在卸载程序时都会删除,因此不会在卸载后还保留乱七八糟的缓存
* 有SD卡时获取 /sdcard/Android/data/<application package>/cache
* 无SD卡时获取 /data/data/<application package>/cache
*
* @param context 上下文
* @param uniqueName 缓存目录下的细分目录,用于存放不同类型的缓存
* @return 缓存目录 File
*/
private File getDiskCacheDir(Context context, String uniqueName) {
String cachePath = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
return new File(cachePath + File.separator + uniqueName);
}
// =======================================
// ===遇到文件比较大的,可以直接通过流读写 =====
// =======================================
//basic editor
public DiskLruCache.Editor editor(String key) {
try {
key = Utils.hashKeyForDisk(key);
//wirte DIRTY
DiskLruCache.Editor edit = mDiskLruCache.edit(key);
//edit maybe null :the entry is editing
if (edit == null) {
Log.w(TAG, "the entry spcified key:" + key + " is editing by other . ");
}
return edit;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//basic get
public InputStream get(String key) {
try {
DiskLruCache.Snapshot snapshot = mDiskLruCache.get(Utils.hashKeyForDisk(key));
if (snapshot == null) //not find entry , or entry.readable = false
{
Log.e(TAG, "not find entry , or entry.readable = false");
return null;
}
//write READ
return snapshot.getInputStream(0);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
// =======================================
// ============== String 数据 读写 =============
// =======================================
public void put(String key, String value) {
DiskLruCache.Editor edit = null;
BufferedWriter bw = null;
try {
edit = editor(key);
if (edit == null) return;
OutputStream os = edit.newOutputStream(0);
bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write(value);
edit.commit();//write CLEAN
} catch (IOException e) {
e.printStackTrace();
try {
edit.abort();//write REMOVE
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
try {
if (bw != null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getAsString(String key) {
InputStream inputStream = null;
inputStream = get(key);
if (inputStream == null) return null;
String str = null;
try {
str = Util.readFully(new InputStreamReader(inputStream, Util.UTF_8));
} catch (IOException e) {
e.printStackTrace();
try {
inputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return str;
}
/******************************************************
* 重载支持 Json数据读写
****************************************************/
public void put(String key, JSONObject jsonObject) {
put(key, jsonObject.toString());
}
public JSONObject getAsJson(String key) {
String val = getAsString(key);
try {
if (val != null)
return new JSONObject(val);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/******************************************************
* 重载支持 JSONArray 读写
****************************************************/
public void put(String key, JSONArray jsonArray) {
put(key, jsonArray.toString());
}
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 读写
****************************************************/
public void put(String key, byte[] value) {
OutputStream outputStream = null;
DiskLruCache.Editor editor = null;
editor = editor(key);
if (editor == null) return;
try {
outputStream = editor.newOutputStream(0);
outputStream.write(value);
outputStream.flush();
editor.commit();
} catch (IOException e) {
e.printStackTrace();
try {
editor.abort();
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public byte[] getAsBytes(String key) {
byte[] ret = null;
InputStream inputStram = get(key);
if (inputStram == null) return null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
byte[] buf = new byte[1024];
int len = 0;
while ((len = inputStram.read(buf)) != -1) {
byteArrayOutputStream.write(buf, 0, len);
}
ret = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStram.close();
byteArrayOutputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return ret;
}
/******************************************************
* 重载支持 Serializable 读写
****************************************************/
public void put(String key, Serializable value) {
ObjectOutputStream outputStream = null;
DiskLruCache.Editor editor = null;
editor = editor(key);
if (editor == null) return;
try {
outputStream = new ObjectOutputStream(editor.newOutputStream(0));
outputStream.writeObject(value);
outputStream.flush();
editor.commit();
} catch (IOException e) {
e.printStackTrace();
try {
editor.abort();
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public <T> T getAsSerializable(String key) {
T ret = null;
InputStream inputStream = get(key);
if (inputStream == null) return ret;
ObjectInputStream objInputStream = null;
try {
objInputStream = new ObjectInputStream(inputStream);
ret = (T) objInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
objInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
public void close() throws IOException {
mDiskLruCache.close();
}
public void delete() throws IOException {
mDiskLruCache.delete();
}
public void flush() throws IOException {
mDiskLruCache.flush();
}
public boolean isClosed() {
return mDiskLruCache.isClosed();
}
public long size() {
return mDiskLruCache.size();
}
public void setMaxSize(long maxSize) {
mDiskLruCache.setMaxSize(maxSize);
}
public File getDirectory() {
return mDiskLruCache.getDirectory();
}
public long getMaxSize() {
return mDiskLruCache.getMaxSize();
}
public DiskLruCache getDiskLruCache() {
return mDiskLruCache;
}
}