1. 程式人生 > >java實現圖片檔案的快取工具實現

java實現圖片檔案的快取工具實現

package com.demo.loading;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.lang.StringUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;

public class ImageFileCache {
	private static final String WHOLESALE_CONV = ".cach";
	/** 過期時間3天 **/
	private static final long mTimeDiff = 3 * 24 * 60 * 60 * 1000;
	private String cardType = null;

	public ImageFileCache() {
		// 清理檔案快取
		removeCache(getDirectory());
	}

	/**
	 * 通過URL獲取圖片
	 * 
	 * @param url
	 * @return Bitmap
	 */
	public Bitmap getImage(final String url) {
		final String path = getDirectory() + "/" + convertUrlToFileName(url);
		File file = new File(path);
		if (file.exists()) {
			Bitmap bmp = BitmapFactory.decodeFile(path);
			if (bmp == null) {
				file.delete();
			} else {
				updateFileTime(path);
				return bmp;
			}
		}
		return null;
	}

	/**
	 * 判斷圖片是否存在
	 * 
	 * @param url
	 */
	public Boolean exists(String url) {
		String path = getDirectory() + "/" + convertUrlToFileName(url);
		File file = new File(path);
		return file.exists();
	}

	/**
	 * 刪除快取檔案
	 * 
	 * @param url
	 */
	public void deleteFile(String url) {
		try {
			if (StringUtils.isNotBlank(url)) {
				final String path = getDirectory() + "/"
						+ convertUrlToFileName(url);
				File file = new File(path);
				if (file != null && file.exists()) {
					file.delete();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/*** 快取空間大小 ****/
	private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;

	/**
	 * 儲存圖片到SD卡
	 * 
	 * @param bm
	 * @param url
	 */
	public void saveBmpToSd(Bitmap bm, String url) {
		if (bm == null) {
			// 需要儲存的是一個空值
			return;
		}

		// 判斷sdcard上的空間
		if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
			// SD空間不足
			return;
		}

		String filename = convertUrlToFileName(url);
		String dir = getDirectory();
		File fileDir = new File(dir);
		if (!fileDir.exists()) {
			fileDir.mkdirs();
		}
		File file = new File(dir + "/" + filename);
		try {
			file.createNewFile();
			OutputStream outStream = new FileOutputStream(file);
			bm.compress(Bitmap.CompressFormat.PNG, 10, outStream);
			outStream.flush();
			outStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 儲存圖片到SD卡
	 * 
	 * @param bData
	 * @param url
	 */
	public void saveBmpToSd(byte[] bData, String url, String cardType) {
		this.cardType = cardType;
		if (bData == null) {
			// 需要儲存的是一個空值
			return;
		}

		// 判斷sdcard上的空間
		if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
			// SD空間不足
			return;
		}

		String filename = convertUrlToFileName(url);
		String dir = getDirectory();
		File fileDir = new File(dir);
		if (!fileDir.exists()) {
			fileDir.mkdirs();
		}
		File file = new File(dir + "/" + filename);
		FileOutputStream fos = null;
		try {
			file.createNewFile();
			fos = new FileOutputStream(file);
			fos.write(bData);
		} catch (Exception e) {
			file.delete();
			e.printStackTrace();
		} finally {
			try {
				fos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private static final int CACHE_SIZE = 10;

	/**
	 * 清理快取 計算儲存目錄下的檔案大小,
	 * 當檔案總大小大於規定的CACHE_SIZE或者sdcard剩餘空間小於FREE_SD_SPACE_NEEDED_TO_CACHE的規定
	 * 那麼刪除40%最近沒有被使用的檔案
	 * 
	 * @param dirPath
	 */
	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(WHOLESALE_CONV)) {
				dirSize += files[i].length();
			}
		}

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

		if (freeSpaceOnSd() <= CACHE_SIZE) {
			return false;
		}
		return true;
	}

	/**
	 * 根據檔案的最後修改時間進行排序*
	 */
	private class FileLastModifSort implements Comparator<File> {
		public int compare(File arg0, File arg1) {
			if (arg0.lastModified() > arg1.lastModified()) {
				return 1;
			} else if (arg0.lastModified() == arg1.lastModified()) {
				return 0;
			} else {
				return -1;
			}
		}
	}

	/**
	 * 刪除過期檔案
	 * 
	 * @param dirPath
	 * @param filename
	 */
	public void removeExpiredCache(String dirPath, String filename) {
		File file = new File(dirPath, filename);
		if (System.currentTimeMillis() - file.lastModified() > mTimeDiff) {
			file.delete();
		}
	}

	/**
	 * 修改檔案的最後修改時間 這裡需要考慮,是否將使用的圖片日期改為當前日期
	 * 
	 * @param path
	 */
	public void updateFileTime(String path) {
		File file = new File(path);
		long newModifiedTime = System.currentTimeMillis();
		file.setLastModified(newModifiedTime);
	}

	/**
	 * 計算sdcard上的剩餘空間
	 * 
	 * @return
	 */
	private int MB = 1024 * 1024;

	/**
	 * 計算sdcard上的剩餘空間
	 * 
	 * @return
	 */
	private int freeSpaceOnSd() {
		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) {
		// String[] strs = url.split("/");
		String fileName = "";
		if (url.contains(".jpg"))
			fileName = cardType + ".jpg";// + WHOLESALE_CONV;
		else if (url.contains(".png"))
			fileName = cardType + ".png";
		return fileName.replaceAll("[?]", "_");
	}

	/** 獲得快取目錄 **/
	private String getDirectory() {
		String dir = getSDPath() + "/" + ConstantUtils.IMAGECACHDIR;
		String substr = dir.substring(0, 4);
		if (substr.equals("/mnt")) {
			dir = dir.replace("/mnt", "");
		}
		return dir;
	}

	/**** 取SD卡路徑不帶/ ****/
	public String getSDPath() {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED); // 判斷sd卡是否存在
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory();// 獲取跟目錄
		}

		if (sdDir != null) {
			return sdDir.toString();
		} else {
			return "";
		}
	}
	/**
	 * http://www.cnblogs.com/TerryBlog/archive/2012/01/08/2316482.html
	 */
}

相關推薦

java實現圖片檔案快取工具實現

package com.demo.loading; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOE

javaweb實現圖片檔案上傳

圖片上傳到檔案中,可以直接上傳圖片到目錄中,也還可以將圖片檔名、檔案路徑寫入到資料庫中,也可以在程式中動態的建立檔案路徑。 參看:http://blog.csdn.net/lmdcszh/article/details/9201173 package com.ioif.wha.ima

Java遍歷檔案樹的實現和測試

突然想寫一下各種遍歷檔案樹的方法, 以下是程式碼, 發現多是以深度優先搜尋為主, 我自己搞了個廣度優先. package com.test; import java.io.File; import java.io.IOException; import java.nio.file.Fi

在Selenium 利用AutoIt實現圖片檔案上傳

1. AutoIT安裝   下載並安裝AutoIT,下載連結:https://www.autoitscript.com/site/autoit/   AutoIT安裝成功後,可以在開始選單下看到AutoIT的所有工具,如下圖所示:   其中分為幾類,AutoIT

iOS開發------實現圖片下載快取到本地

      在開發過程中很多人都會使用SDWebImage來進行網路圖片的快取,說實話,這個第三方也確實好用,但依照本人的性格,還是一直在想做一版自己的本地快取,比如下載的圖片存到本地,下次再有相同的圖片需要載入,就不用再花冤枉流量來下載了,這次的嘗試雖然相比SDWebIm

用Glide去實現圖片快取和瀑布流

效果圖: 上面的加號和回收箱能實現載入一個圖片和刪除一個圖片,結合上一篇實現的圖片的載入用Glide實現圖片的快取,這次我們用RecyclerView來做,下面直接上程式碼,有問題留言大家一起探討… MainActivity程式碼: public

IOS開發之非同步載入網路圖片快取本地實現瀑布流(一)

</pre><pre name="code" class="objc"></pre><pre name="code" class="objc">在前面的一篇部落格中,我寫了一個瀑布流照片牆的程式,由於之前的程式載入的圖片是本

Java自動過期本地快取簡單實現

實際專案中常常需要用到本地快取,特別是一些固定不變的資料,不想頻繁調介面,因為http請求本身需要耗時,下面幾個類對本地快取作了簡單實現,支援自動過期功能LocalCache.javainterface LocalCache { public void refresh()

javascript 使用FormData實現圖片/檔案非同步上傳

主要思路: 在html中新增上傳按鈕,為了方便,這裡使用<img>作為上傳按鈕,監聽<img>點選事件,在事件處理函式中,建立<input type="file">標籤,註冊<input type="file">

Java讀取大檔案的高效率實現

1、概述本教程將演示如何用Java高效地讀取大檔案。Java——迴歸基礎。 2、在記憶體中讀取讀取檔案行的標準方式是在記憶體中讀取,Guava 和Apache Commons IO都提供瞭如下所示快速讀取檔案行的方法:Files.readLines(new File(pat

Matlab批量實現圖片檔案格式轉換

for n=0:1673   str1='G:\obj\';str2=num2str(n);str3='.png'; SC=[str1,str2,str3];              i=imrea

通過純css實現圖片居中的多種實現方式

splay add pad src 純css webkit web center -c html結構: 1 <div class="demo" style="width: 800px;height: 600px; border:1px solid #ddd">

java 讀取properties檔案通用工具

1.建立 PropertiesUtil.java檔案: package com.demo.util; import java.util.ResourceBundle; /** * 對系統中的config.properties配置檔案內容讀取工具類 * * Created by zha

Java建立圖片檔案縮圖

public static void uploadImg(InputStream file, String filePath, String fileName, int widthdist, int heightdist) throws Exception { File targetDir = new

JAVA 到處excel檔案工具

import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org

Java圖片檔案的複製

一、位元組流介紹       1、位元組輸出流 OutputStream類定義 public abstract class OutputStream extends Object implements Closeable, Flushable  此抽象類是表示輸出位元組流的

儲存圖片檔案工具

用法 先定義一個 全域性變數 private SaveToSdCardUtil saveToSdCardUtil; 初始化工具類 在oncreate 中 saveToSdCardUtil = new SaveToSdCardUtil(context

java圖片新增水印工具

      給圖片新增水印這個功能以前做專案的時候遇到過 但是後來好久不用今天突然想起來  就隨筆記錄一下吧  隨便在記錄一下自己當初踩的坑 package Img; import java.awt.Color; import jav

Java讀取圖片檔案的寬度和高度

InputStream is = new FileInputStream(filename);//通過檔名稱讀取 或 InputStream is =new ByteArrayInputStream(byte[] a);//通過檔案的位元組陣列讀取 BufferedImag

Java的Excel檔案操作工具類,包括讀、寫、合併等功能

一、直接上程式碼: package com.cycares.crm.utils.ExcelUtil; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputS