Добавил кэширование поскейленных картинок, чтобы расходовать меньше батарейки и сетевого трафика
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user