Добавил кэширование поскейленных картинок, чтобы расходовать меньше батарейки и сетевого трафика

This commit is contained in:
ftc
2021-05-27 23:59:12 +03:00
parent 98da719fcc
commit ca893f8687
7 changed files with 231 additions and 19 deletions
+160
View File
@@ -0,0 +1,160 @@
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class Cache
{
const int MAX_ELEMENTS = 1000;
const string CACHE_DESCRIPTION_FILE = "files.dat";
const string CACHE_DATA_DIR = "data";
private string rootPath;
private CacheDescription description;
public Cache(string path)
{
rootPath = path;
if (!Directory.Exists(GetDataPath()))
{
Directory.CreateDirectory(GetDataPath());
}
LoadDescription();
CleanupDataDirectory();
}
private string GetDataPath()
{
return rootPath + "/" + CACHE_DATA_DIR;
}
private void CleanupDataDirectory()
{
var directory = GetDataPath();
var di = new DirectoryInfo(directory);
var files = di.GetFiles();
foreach (var f in files)
{
if (!description.path.ContainsKey(f.Name))
{
File.Delete(directory + "/" + f.Name);
}
}
}
private string RandomName()
{
string result = "";
for (int i = 0; i < 30; i++)
{
int t = UnityEngine.Random.Range(0, 36);
if (t < 10) result += (char)(t + '0');
else result += (char)(t - 10 + 'a');
}
return result;
}
private void LoadDescription()
{
var path = rootPath + "/" + CACHE_DESCRIPTION_FILE;
try
{
if (File.Exists(path))
{
Stream openFileStream = File.OpenRead(path);
BinaryFormatter deserializer = new BinaryFormatter();
description = (CacheDescription)deserializer.Deserialize(openFileStream);
openFileStream.Close();
}
else
{
description = new CacheDescription();
}
}
catch (Exception)
{
description = new CacheDescription();
}
}
public void Add(string path, byte[] data)
{
if (!description.path.ContainsKey(path))
{
while (true)
{
var fileName = RandomName();
if (!File.Exists(GetDataPath() + "/" + fileName))
{
description.path[path] = fileName;
break;
}
}
}
var filePath = GetDataPath() + "/" + description.path[path];
File.WriteAllBytes(filePath, data);
description.lastUse[path] = DateTime.Now;
PurgeCache();
SaveDescription();
}
private void SaveDescription()
{
var path = rootPath + "/" + CACHE_DESCRIPTION_FILE;
try
{
BinaryFormatter serializer = new BinaryFormatter();
Stream openFileStream = File.OpenWrite(path);
serializer.Serialize(openFileStream, description);
openFileStream.Close();
}
catch (Exception)
{
description = new CacheDescription();
}
}
private void PurgeCache()
{
// throw away excess elements
// for now will use slow implementation
while (description.path.Count >= MAX_ELEMENTS)
{
DateTime min = DateTime.MaxValue;
string mpath = null;
foreach (var kv in description.lastUse)
{
if (kv.Value < min)
{
min = kv.Value;
mpath = kv.Key;
}
}
// not found?
if (mpath == null) break;
try
{
File.Delete(GetDataPath() + "/" + description.path[mpath]);
}
catch (IOException) { }
description.path.Remove(mpath);
description.lastUse.Remove(mpath);
}
}
public byte[] Get(string path)
{
if (!description.path.ContainsKey(path))
{
return null;
}
try
{
description.lastUse[path] = DateTime.Now;
return File.ReadAllBytes(GetDataPath() + "/" + description.path[path]);
}
catch (IOException)
{
return null;
}
}
}