fileCacheDir=C:\\Users\\Administrator\\Desktop\\deploy
2、设置文件缓存路径
@Configuration
public class FileCacheConfig {
@Value("${fileCacheDir}")
private String fileCacheDir;
@Bean
public FileCache getFileCache(){
return new FileCache(fileCacheDir);
}
}
3、操作文件缓存对象
接口
public interface ICache {
/**
* 根据key获取缓存数据
* @param key 存储key
* @return 缓存到文件中的数据
*/
T get(String key) throws IOException, ClassNotFoundException, Exception;
/**
* 添加缓存
* @param key 存储key
* @param data 缓存到文件中的数据
*/
int set(String key, Object data) throws IOException;
/**
* 删除
* @return 删除影响的行数
*/
int delete(String key);
}
具体操作类:
public class FileCache implements ICache {
private String cacheDir;
public FileCache(String cacheDir) {
this.cacheDir = cacheDir;
}
@Override
public Object get(String key) throws Exception {
File file = new File(this.getRealFilePath(key));
if (!file.exists()) {
return null;
}
//获取文件中对象
Object fileObject = FileOperate.getFileObject(file);
Object fileStorageObject = null;
if ( fileObject instanceof FileCacheObject) {
FileCacheObject fcObject = (FileCacheObject)fileObject;
//查看缓存是否过期
if (!fcObject.isCacheExpire()) {
fileStorageObject = fcObject.getStorageObject();
}
}
//如果不存在活已经过期就删除
if (null == fileStorageObject) {
file.delete();
}
return fileStorageObject;
}
@Override
public int set(String key, Object data) throws IOException {
String filePath = this.getRealFilePath(key);
return FileOperate.saveObjectToFile(filePath, new FileCacheObject(data)) ? 1 : 0;
}
@Override
public int delete(String key) {
String filePath = this.getRealFilePath(key);
File file = new File(filePath);
if (!file.exists()) {
return 1;
}else {
return file.delete() ? 1 : 0;
}
}
/**
* 获取cache 所存的文件相对路径
* @param cacheId 缓存id
*/
protected String getRealFilePath(String cacheId) {
StringBuilder sb = new StringBuilder(cacheDir);
if (!cacheDir.endsWith(File.separator)) {
sb.append(File.separator);
}
cacheId = cacheId.toLowerCase();
sb.append(DigestUtils.md5DigestAsHex(cacheId.getBytes()));
return sb.toString();
}
}
4、对接文件和对象转化文件操作类
public class FileOperate {
public final static String DEFAULT_ENCODING = "UTF-8";
/**
* 获取文件路径对应文件对象
*/
public static Object getFileObject(String filePath) throws IOException, ClassNotFoundException {
return getFileObject(new File(filePath));
}
/**
* 读取文件中的对象
*/
public static Object getFileObject(File file) throws IOException, ClassNotFoundException {
if (!file.exists()) {
return null;
}
try(ObjectInputStream ois=new ObjectInputStream(new FileInputStream(file))){
return ois.readObject();
}
}
/**
* 读取文件路劲对应文件的内容
* @param filePath 文件路径
* @param encoding 编码格式
* @return 文件对象
*/
public static String getFileContent(String filePath,String encoding) throws IOException {
return getFileContent(new File(filePath), encoding);
}
/**
* 读取文件的文本内容
*/
public static String getFileContent(File file,String encoding) throws IOException {
if (!file.exists()) {
return null;
}
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
encoding = StringUtils.isEmpty(encoding) ? DEFAULT_ENCODING : encoding;
int readLen;
byte[] data = new byte[4096];
while ((readLen = bis.read(data)) != -1) {
baos.write(data, 0, readLen);
}
return baos.toString(encoding);
}
}
/**
* 读取文件大小
*/
public static long getFileLength(File file) throws IOException {
if (!file.exists()) {
return 0;
}
long total = 0;
try(FileInputStream fis=new FileInputStream(file)){
while (true) {
int expect = fis.available();
if (expect < 0) {
break;
}
skip(fis,expect);
total += expect;
}
}
return total;
}
public static void skip(FileInputStream fis, long expect) throws IOException {
int maxTryTime = 16;
while (expect > 0 && maxTryTime-- > 0) {
long current = fis.skip(expect);
if (current == expect) {
return;
}else {
expect -= current;
}
}
}
/**
* 保存内荣到文件
*/
public static boolean saveContentToFile(String filePath, String content) throws IOException {
return saveContentToFile(filePath, content, null);
}
/**
* 保存内荣到文件
*/
public static boolean saveContentToFile(String filePath, String content,String encoding) throws IOException {
if (StringUtils.isEmpty(encoding)) {
encoding = DEFAULT_ENCODING;
}
return saveContentToFile(filePath, content.getBytes(encoding));
}
/**
* 保存内容到文件
*/
public static boolean saveContentToFile(String filePath, byte[] data) throws IOException {
if(!FileOperate.createDir(filePath,true)){
return false;
}
try (FileOutputStream fos = new FileOutputStream(filePath)) {
fos.write(data);
fos.flush();
return true;
}
}
/**
* 保存对象到文件中
*/
public static boolean saveObjectToFile(String filePath, Object obj) throws IOException {
if(!FileOperate.createDir(filePath,true)){
return false;
}
try (ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(filePath))){
oos.writeObject(obj);
oos.flush();
return true;
}
}
/**
* 创建目录
*/
public static boolean createDir(String path, boolean isFile) {
File file = new File(path);
if (isFile) {
file = file.getParentFile();
}
if (!file.exists()) {
return file.mkdirs();
}else {
return true;
}
}
}
5、缓存对象类
@Data
public class FileCacheObject implements Serializable {
private static final long serialVersionUID = 908523022948306952L;
private long createTime;
private long timeout;
private Object storageObject;
public FileCacheObject() {
}
public FileCacheObject(Object storageObject) {
this(Integer.MAX_VALUE, storageObject);
}
public FileCacheObject(long timeout, Object storageObject) {
if (!(storageObject instanceof Serializable)) {
throw new IllegalArgumentException("storage object must implement Serializable");
}
this.createTime = System.currentTimeMillis();
this.timeout = timeout;
this.storageObject = storageObject;
}
/**
* 缓存是否过期
* @return 缓存存是否过期
*/
public boolean isCacheExpire(){
//等于0 表示无过期时间
if (timeout == 0) {
return false;
}
return createTime + timeout < System.currentTimeMillis();
}
}
7、测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class FileCacheTest {
@Resource
private FileCache fileCache;
private static final String FILE_CACHE_KEY = "file_cache_key";
@Test
public void loadData() throws Exception {
List users = new ArrayList<>();
User user1 = User.builder().id(1L).accountBalance(1L).email("email1").headPic("pic1").build();
User user12 = User.builder().id(2L).accountBalance(2L).email("email2").headPic("pic2").build();
users.add(user1);
users.add(user12);
fileCache.set(FILE_CACHE_KEY, users);
List userList2= (List)fileCache.get(FILE_CACHE_KEY);
System.out.println(userList2);
}
}
附上User类:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private Long id;
private String username;
private String password;
private String phone;
private String email;
private Date created;
private Date updated;
private String sourceType;
private String nickName;
private String name;
private String status;
private String headPic;
private String qq;
private Long accountBalance;
private String isMobileCheck;
private String isEmailCheck;
private String sex;
private Integer userLevel;
private Integer points;
private Integer experienceValue;
private Date birthday;
private Date lastLoginTime;
}