您的位置:首页 > 理论基础 > 计算机网络

android中图片的三级cache策略(内存、文件、网络)之三:文件缓存策略 .

2015-10-25 21:32 615 查看

文件缓存策略

当一张图片从网络下载成功以后,这个图片会被加入内存缓存和文件缓存,对于文件缓存来说,这张图片将被以url的哈希值加cach后缀名的形式存储在SD卡上,这样,当下一次再需要同一个url的图片的时候,就不需要从网络下载了,而是直接通过url来进行查找。同时一张图片被访问时,它的最后修改时间将被更新,这样的意义在于:当SD卡空间不足的时候,将会按照最后修改时间来删除40%缓存的图片,确切来说,那些修改时间比较早的图片将会被删除。

代码展示

public class ImageFileCache
{
private static final String TAG = "ImageFileCache";

//图片缓存目录
private static final String IMGCACHDIR = "/sdcard/ImgCach";

//保存的cache文件宽展名
private static final String CACHETAIL = ".cach";

private static final int MB = 1024*1024;

private static final int CACHE_SIZE = 1;

//当SD卡剩余空间小于10M的时候会清理缓存
private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;

public ImageFileCache()
{
//清理部分文件缓存
removeCache(IMGCACHDIR);
}

/**
* 从缓存中获取图片
*/
public Bitmap getImageFromFile(final String url)
{
final String path = IMGCACHDIR + "/" + convertUrlToFileName(url);
File file = new File(path);
if (file != null && file.exists())
{
Bitmap bmp = BitmapFactory.decodeFile(path);
if (bmp == null)
{
file.delete();
}
else
{
updateFileTime(path);
Logger.d(TAG, "get bmp from FileCache,url=" + url);
return bmp;
}
}
return null;
}

/**
* 将图片存入文件缓存
*/
public void saveBitmapToFile(Bitmap bm, String url)
{
if (bm == null) {
return;
}
//判断sdcard上的空间
if (FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace())
{
//SD空间不足
return;
}

String filename = convertUrlToFileName(url);
File dirFile = new File(IMGCACHDIR);
if (!dirFile.exists())
dirFile.mkdirs();
File file = new File(IMGCACHDIR +"/" + filename);
try
{
file.createNewFile();
OutputStream outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
}
catch (FileNotFoundException e)
{
Logger.d(TAG, "FileNotFoundException");
}
catch (IOException e)
{
Logger.d(TAG, "IOException");
}
}

/**
* 计算存储目录下的文件大小,
* 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
* 那么删除40%最近没有被使用的文件
*/
private boolean removeCache(String dirPath)
{
File dir = new File(dirPath);
File[] files = dir.listFiles();

if (files == null)
{
return true;
}

if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
return false;
}

int dirSize = 0;
for (int i = 0; i < files.length; i++)
{
if (files[i].getName().contains(CACHETAIL))
{
dirSize += files[i].length();
}
}

if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace())
{
int removeFactor = (int) (0.4 * files.length);
Arrays.sort(files, new FileLastModifSort());
for (int i = 0; i < removeFactor; i++)
{
if (files[i].getName().contains(CACHETAIL))
{
files[i].delete();
}
}
}

if (SdCardFreeSpace() <= CACHE_SIZE)
{
return false;
}

return true;
}

/**
* 修改文件的最后修改时间
*/
public void updateFileTime(String path)
{
File file = new File(path);
long newModifiedTime = System.currentTimeMillis();
file.setLastModified(newModifiedTime);
}

/**
* 计算SD卡上的剩余空间
*/
private int SdCardFreeSpace()
{
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
return (int) sdFreeMB;
}

/**
* 将url转成文件名
*/
private String convertUrlToFileName(String url)
{
return url.hashCode() + CACHETAIL;
}

/**
* 根据文件的最后修改时间进行排序
*/
private class FileLastModifSort implements Comparator<File>
{
public int compare(File file0, File file1)
{
if (file0.lastModified() > file1.lastModified())
{
return 1;
}
else if (file0.lastModified() == file1.lastModified())
{
return 0;
}
else
{
return -1;
}
}
}

}

说明:上述代码很好理解而且都有注释,不用多说了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: