package com.mcxiaoke.next.cache;
import android.content.Context;
import com.mcxiaoke.next.Charsets;
import com.mcxiaoke.next.io.NameGenerator;
import com.mcxiaoke.next.io.SafeFileNameGenerator;
import com.mcxiaoke.next.utils.AndroidUtils;
import com.mcxiaoke.next.utils.IOUtils;
import com.mcxiaoke.next.utils.LogUtils;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
/**
* User: mcxiaoke
* Date: 14-3-21
* Time: 18:19
*/
public class DiscCache implements IDiscCache {
public static final String TAG = DiscCache.class.getSimpleName();
/**
* 指定使用内部存储,外部存储,还是自动选择
*/
public static final int MODE_INTERNAL = 0;
public static final int MODE_EXTERNAL = 1;
public static final int MODE_AUTO = 2;
private int mMode = MODE_AUTO;
public static final String DIR_NAME_DEFAULT = ".disc";
private static boolean sDebug;
private Context mContext;
private File mCacheDir;
private String mCacheDirName;
private NameGenerator mGenerator = new SafeFileNameGenerator();
private Charset mCharset = Charsets.UTF_8;
public DiscCache(Context context) {
this(context, DIR_NAME_DEFAULT);
}
public DiscCache(Context context, String dirName) {
this(context, dirName, MODE_AUTO);
}
public DiscCache(Context context, String dirName, int mode) {
if (sDebug) {
LogUtils.v(TAG, "DiscCache() cacheDirName=" + dirName);
}
mContext = context;
setCacheDir(dirName, mode);
}
public static void setDebug(boolean debug) {
LogUtils.v(TAG, "setDebug() debug=" + debug);
DiscCache.sDebug = debug;
}
/**
* 设置缓存文件夹的名字
*
* @param dirName Dir Name
*/
public void setCacheDir(String dirName, int mode) {
if (sDebug) {
LogUtils.v(TAG, "setCacheDir() dirName=" + dirName + " mode=" + mode);
}
if (dirName == null) {
mCacheDirName = DIR_NAME_DEFAULT;
} else {
mCacheDirName = dirName;
}
mMode = mode;
checkCacheDir(true);
}
/**
* 直接设置完整的缓存路径,调试用
*
* @param cacheDir Cache Dir
*/
public void setDebugCacheDir(File cacheDir) {
if (sDebug) {
LogUtils.v(TAG, "setCacheDir() cacheDir=" + cacheDir);
}
mCacheDir = cacheDir;
checkCacheDir(false);
}
public void setCharset(String charset) {
if (sDebug) {
LogUtils.v(TAG, "setCharset() charset=" + charset);
}
mCharset = Charsets.toCharset(charset);
}
public void setCharset(Charset charset) {
if (sDebug) {
LogUtils.v(TAG, "setCharset() charset=" + charset);
}
mCharset = Charsets.toCharset(charset);
}
public void setFileNameGenerator(NameGenerator generator) {
mGenerator = generator;
}
@Override
public void put(String key, byte[] data) {
checkCacheDir(false);
try {
if (sDebug) {
LogUtils.v(TAG, "put() bytes key=" + key);
}
IOUtils.writeBytes(getFile(key), data);
} catch (IOException ignored) {
if (sDebug) {
ignored.printStackTrace();
LogUtils.e(TAG, "put() key=" + key + " error=" + ignored);
}
}
}
@Override
public void put(String key, InputStream stream) {
checkCacheDir(false);
try {
if (sDebug) {
LogUtils.v(TAG, "put() stream key=" + key);
}
IOUtils.writeStream(getFile(key), stream);
} catch (IOException ignored) {
if (sDebug) {
ignored.printStackTrace();
LogUtils.e(TAG, "put() key=" + key + " error=" + ignored);
}
}
}
@Override
public void put(String key, String text) {
checkCacheDir(false);
try {
if (sDebug) {
LogUtils.v(TAG, "put() string key=" + key);
}
IOUtils.writeString(getFile(key), text);
} catch (IOException ignored) {
if (sDebug) {
ignored.printStackTrace();
LogUtils.e(TAG, "put() key=" + key + " error=" + ignored);
}
}
}
@Override
public String get(String key) {
try {
String value = IOUtils.readString(getFile(key), mCharset);
if (sDebug) {
LogUtils.v(TAG, "get() key=" + key + " value=" + value);
}
return value;
} catch (IOException ignored) {
if (sDebug) {
ignored.printStackTrace();
LogUtils.e(TAG, "put() key=" + key + " error=" + ignored);
}
return null;
}
}
@Override
public File getFile(String key) {
File file = getCacheFile(key);
if (sDebug) {
LogUtils.v(TAG, "getFile() key=" + key + " file=" + file);
}
return file;
}
@Override
public byte[] getBytes(String key) {
File file = getFile(key);
try {
return IOUtils.readBytes(file);
} catch (IOException ignored) {
if (sDebug) {
ignored.printStackTrace();
LogUtils.e(TAG, "put() key=" + key + " error=" + ignored);
}
return null;
}
}
@Override
public boolean remove(String key) {
File file = getFile(key);
if (sDebug) {
LogUtils.v(TAG, "remove() key=" + key + " file=" + file);
}
return IOUtils.delete(file);
}
@Override
public void clear() {
if (sDebug) {
LogUtils.v(TAG, "clear()");
}
IOUtils.delete(mCacheDir);
checkCacheDir(false);
}
@Override
public int delete(FileFilter filter) {
File cacheDir = getCacheDir();
File[] files = cacheDir.listFiles();
if (files == null || files.length == 0) {
return 0;
}
int count = 0;
for (File file : files) {
if (filter.accept(file)) {
if (sDebug) {
LogUtils.v(TAG, "trim() file=" + file.getPath());
}
// no recursion
file.delete();
}
}
if (sDebug) {
LogUtils.v(TAG, "trim() count=" + count);
}
return count;
}
@Override
public File getCacheDir() {
checkCacheDir(false);
return mCacheDir;
}
public void setCacheDir(String dirName) {
setCacheDir(dirName, MODE_AUTO);
}
@Override
public long getCacheSize() {
return IOUtils.sizeOf(getCacheDir());
}
private void checkCacheDir(boolean forceSet) {
if (mCacheDir == null || forceSet) {
mCacheDir = new File(getBaseCacheDir(), mCacheDirName);
}
if (!mCacheDir.exists()) {
mCacheDir.mkdirs();
}
if (sDebug) {
LogUtils.v(TAG, "checkCacheDir() cacheDir=" + mCacheDir + " forceSet=" + forceSet);
}
}
private File getCacheFile(String key) {
String fileName = mGenerator.generate(key);
if (sDebug) {
LogUtils.v(TAG, "getCacheFile() key=" + key + " fileName=" + fileName);
}
return new File(mCacheDir, fileName);
}
private File getBaseCacheDir() {
File baseCacheDir;
switch (mMode) {
case MODE_INTERNAL: {
baseCacheDir = mContext.getCacheDir();
}
break;
case MODE_EXTERNAL: {
baseCacheDir = mContext.getExternalCacheDir();
}
break;
case MODE_AUTO:
default: {
if (AndroidUtils.isMediaMounted()) {
baseCacheDir = mContext.getExternalCacheDir();
} else {
baseCacheDir = mContext.getCacheDir();
}
break;
}
}
return baseCacheDir;
}
}