java实现图片文件的缓存工具实现

30 篇文章 0 订阅
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
	 */
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是springboot实现网页图片缓存到本地的步骤: 1. 在pom.xml文件中添加以下依赖: ``` <!-- Spring Boot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Apache Commons IO --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> ``` 2. 创建一个名为FileUtil的工具类,用于保存图片到本地文件系统中: ``` import org.apache.commons.io.FileUtils; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; public class FileUtil { public static void saveImage(MultipartFile image, String path, String filename) throws IOException { File file = new File(path); if (!file.exists()) { file.mkdirs(); } FileUtils.copyInputStreamToFile(image.getInputStream(), new File(path, filename)); } } ``` 3. 在Controller中添加以下方法,用于下载网页中的图片并保存到本地: ``` import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.net.URL; import java.util.List; import java.util.UUID; @Controller public class HomeController { @Value("${image.path}") private String imagePath; @GetMapping("/") public String index() { return "index"; } @PostMapping("/") public String uploadImages(@RequestParam("url") String url, Model model) throws IOException { List<String> imageUrls = HTMLUtil.getImageUrls(url); for (String imageUrl : imageUrls) { URL imageLink = new URL(imageUrl); String imageFileType = imageUrl.substring(imageUrl.lastIndexOf('.') + 1); String imageName = UUID.randomUUID().toString() + "." + imageFileType; FileUtil.saveImage(imageLink.openStream(), imagePath, imageName); } model.addAttribute("message", "Images saved successfully"); return "index"; } } ``` 4. 在application.properties文件中添加以下配置,用于指定保存图片的目录: ``` image.path=/tmp/images/ ``` 5. 创建一个名为HTMLUtil的工具类,用于从网页中提取图片的链接: ``` import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class HTMLUtil { public static List<String> getImageUrls(String url) throws IOException { Document doc = Jsoup.connect(url).get(); List<String> imageUrls = new ArrayList<>(); doc.select("img").forEach(element -> { String src = element.attr("src"); if (!src.startsWith("http")) { src = "http://" + src; } imageUrls.add(src); }); return imageUrls; } } ``` 现在,当用户提交一个网址时,程序会提取出网页中的所有图片,将它们缓存到本地目录中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值