ImageKnife/entry/src/main/ets/MainAbility/cache/DiskLruCache.ets

317 lines
8.5 KiB
Plaintext

/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomMap} from './CustomMap'
import {FileUtils} from './FileUtils'
import {FileReader} from './FileReader'
import {DiskCacheEntry} from './DiskCacheEntry'
import fileio from '@ohos.fileio';
import featureability from '@ohos.ability.featureAbility'
import {Md5} from './Md5.ets'
export class DiskLruCache {
// 缓存数据集合
cacheMap: CustomMap<string, DiskCacheEntry> = new CustomMap<string, DiskCacheEntry>()
fileUtils: FileUtils = FileUtils.getInstance()
diskCacheFolder: string = 'GlideDiskCache'
// 缓存文件路劲地址
dirPath: string= ''
// 缓存数据最大值
maxSize: number = 30 * 1024 * 1024
// 当前缓存数据值
size: number = 0
// 缓存journal文件名称
journal: string = 'journal'
// 缓存journal备份文件名称
journalTemp: string = 'journal_temp'
// 缓存journal文件路径
journalPath: string = ''
// 缓存journal备份文件路径
journalPathTemp: string = ''
constructor(maxSize: number, direction?: string) {
if (maxSize > 0) {
this.maxSize = maxSize
}
if (!this.isNull(direction)) {
if (direction.endsWith('/')) {
this.dirPath = direction
} else {
this.dirPath = direction + '/'
}
} else {
featureability.getContext()
.getFilesDir()
.then((data) => {
console.log('DiskLruCache - FileDir= ' + data)
let dirPathFolder = data + '/' + this.diskCacheFolder
this.dirPath = dirPathFolder;
FileUtils.getInstance()
.createFolder(dirPathFolder)
this.init()
})
.catch((error) => {
console.log('DiskLruCache FileDir Error Cause:' + error.message);
})
}
}
/**
* 初始化缓存文件
*/
private init() {
if (this.dirPath.endsWith('/')) {
this.dirPath = this.dirPath
} else {
this.dirPath = this.dirPath + '/'
}
this.journalPath = this.dirPath + this.journal
this.journalPathTemp = this.dirPath + this.journalTemp
try {
var stat = fileio.statSync(this.journalPath)
if (stat.isFile() && stat.size > 0) {
this.fileUtils.createFile(this.journalPathTemp)
this.fileUtils.copyFile(this.journalPath, this.journalPathTemp)
this.readJournal(this.journalPathTemp)
this.resetJournalFile()
} else {
this.fileUtils.createFile(this.journalPath)
}
} catch (e) {
console.log('DiskLruCache - init e ' + e)
this.fileUtils.createFile(this.journalPath)
}
}
/**
* 重置journal文件数据
*/
resetJournalFile(){
this.fileUtils.clearFile(this.journalPath)
for(let key of this.cacheMap.keys()){
this.fileUtils.writeData(this.journalPath, 'save ' + key + '\n')
}
}
/**
* 读取journal文件的缓存数据
*/
readJournal(path: string) {
var fileReader = new FileReader(path)
var line: string = ''
while (!fileReader.isEnd()) {
line = fileReader.readLine()
line = line.replace('\n', '').replace('\r', '')
this.dealwithJournal(line)
}
this.fileUtils.deleteFile(this.journalPathTemp)
this.trimToSize()
}
/**
* 处理journal文件数据
*/
dealwithJournal(line: string) {
var picPath = ''
try {
var datas = line.split(' ')
if (datas.length > 1) {
if (datas[0] != 'remove') {
picPath = this.dirPath + datas[1]
var picstat = fileio.statSync(picPath)
if (picstat.isFile() && picstat.size > 0) {
this.size = this.size + picstat.size
this.fileUtils.writeData(this.journalPath, line + '\n')
this.putCacheMap(datas[1], picstat.size)
}
} else {
if (this.cacheMap.hasKey(datas[1])) {
var cacheEntry: DiskCacheEntry = this.cacheMap.get(datas[1])
this.size = this.size - cacheEntry.getLength()
this.cacheMap.remove(datas[1])
}
}
}
} catch (e) {
console.log('DiskLruCache - dealwithJournal e = ' + e)
}
}
/**
* 设置disk缓存最大数据值
*/
setMaxSize(max: number) {
this.maxSize = max
}
/**
* 缓存数据map集合
*/
private putCacheMap(key: string, length?: number) {
if (this.cacheMap.hasKey(key)) {
this.cacheMap.remove(key)
}
if (length > 0) {
this.cacheMap.put(key, new DiskCacheEntry(key, length))
} else {
this.cacheMap.put(key, new DiskCacheEntry(key))
}
}
/**
* 存储disk缓存数据
*/
putCacheData(key: string, content?: ArrayBuffer, path?: string) {
if (key == null) {
throw new Error('key is null,checking the parameter');
}
var fileSize = 0
var isvalid: boolean = false
key = Md5.hashStr(key)
if (content != null && content.byteLength > 0) {
isvalid = true
var tempPath = this.dirPath + key
fileSize = content.byteLength
this.fileUtils.writePic(tempPath, content)
}
if (!this.isNull(path) && this.fileUtils.exist(path)) {
isvalid = true
fileSize = this.fileUtils.getFileSize(path)
this.fileUtils.copyFile(path, this.dirPath + key)
}
if (isvalid) {
this.size = this.size + fileSize
this.putCacheMap(key, fileSize)
this.fileUtils.writeData(this.journalPath, 'save ' + key + '\n')
this.trimToSize()
} else {
throw ('putCacheData() key or content or path is invalid')
}
}
/**
* 根据LRU算法删除多余缓存数据
*/
private trimToSize() {
while (this.size > this.maxSize) {
var tempkey: string = this.cacheMap.getFirstKey()
var fileSize = this.fileUtils.getFileSize(this.dirPath + tempkey)
if (fileSize > 0) {
this.size = this.size - fileSize
}
this.fileUtils.deleteFile(this.dirPath + tempkey)
this.cacheMap.remove(tempkey)
this.fileUtils.writeData(this.journalPath, 'remove ' + tempkey + '\n')
}
}
/**
* 获取key缓存数据
*/
getCacheDataByKey(key: string): ArrayBuffer{
if (key == null) {
throw new Error('key is null,checking the parameter');
}
key = Md5.hashStr(key)
var path = this.dirPath + key;
if (this.fileUtils.exist(path)) {
var ab: ArrayBuffer = this.fileUtils.readFilePic(path)
this.putCacheMap(key, ab.byteLength)
this.fileUtils.writeData(path, 'read ' + key + '\n')
return ab
} else {
return null;
}
}
/**
* 获取key缓存数据绝对路径
*/
getCacheFileByKey(key: string): string{
if (key == null) {
throw new Error('key is null,checking the parameter');
}
key = Md5.hashStr(key)
if (this.dirPath.endsWith('/')) {
this.dirPath = this.dirPath
} else {
this.dirPath = this.dirPath + '/'
}
var path = this.dirPath + key;
if (this.fileUtils.exist(path)) {
this.fileUtils.writeData(path, 'read ' + key + '\n')
return path
} else {
return null
}
}
/**
* 删除key缓存数据
*/
deleteCacheDataBykey(key: string): DiskCacheEntry{
if (key == null) {
throw new Error('key is null,checking the parameter');
}
key = Md5.hashStr(key)
var path = this.dirPath + key;
if (this.fileUtils.exist(path)) {
var ab = this.fileUtils.readFilePic(path)
this.size = this.size - ab.byteLength
this.cacheMap.remove(key)
this.fileUtils.writeData(this.journalPath, 'remove ' + key + '\n')
this.fileUtils.deleteFile(path)
}
return this.cacheMap.get(key)
}
/**
* 清除所有disk缓存数据
*/
cleanCacheData() {
var length = this.cacheMap.size()
for (var index = 0; index < length; index++) {
this.fileUtils.deleteFile(this.dirPath + this.cacheMap[index])
}
this.fileUtils.deleteFile(this.journalPath)
this.cacheMap.clear()
this.size = 0
}
/**
* 空字符串判断
*/
private isNull(str: string): boolean{
if (!str || Object.keys(str).length == 0) {
return true
} else {
return false
}
}
foreachDiskLruCache(fn){
this.cacheMap.each(fn)
}
}