我正在优化一个占用大量磁盘空间的应用程序,该应用程序会生成大量临时文件,但由于存储空间有限,我每天都必须清理文件夹。所以,我想知道什么是最好的方法。这些文件位于网络磁盘上,可通过IIS上的虚拟文件夹进行访问,因此它们看起来像是站点自己的文件夹的一部分。
我有一个在线PDF编辑器,使用Aspose.PDF for .Net。 在使用该应用程序时,它会生成许多临时文件,但仅在创建所有临时文件后才呈现视图。因此,我正在使用Parallel.For语句来进行临时文件创建,限于机器上可用处理器的数量。
最初是按顺序完成的,并且考虑到每页大约需要1到3秒的时间,具体取决于页面质量(Aspose限制,无法对其进行优化),它花费的时间太长。我已经设法使操作并行化,但是时间仍然太长。
另一方面,我有一个例程可以删除多个目录中所有早于24小时(86400秒)的文件。首先,这是根据每个用户请求(页面加载)完成的,因此它在页面生命周期中执行了几次,每次都只删除一堆文件。 所有IIS应用程序池每天都会在00小时进行回收,因此现在我要在Application_Start上进行此操作,但是我担心它会减慢第一个用户请求的速度,因为它必须删除约4.5万个文件(今天,该应用程序已删除已使用了7个小时,已经有3万个文件)。我想知道是否有更好的方法来执行以下操作:
-在Session_End删除一些旧文件(例如,删除4小时之前的文件)
-在Application_End(大于24小时)上删除其余的(如果有的话)。
此外,假设我不必等待它们完成,就可以通过使用异步任务来调用此例程。
对于删除,我在for循环上使用System.IO.FileInfo.Delete()。
临时文件创建过程
Parallel.For(0, TotalPages, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, pageCount =>
{
using (MemoryStream imageStream = new MemoryStream())
{
var po = new PageObject();
var idx = pageCount + 1;
PngDevice p = new PngDevice(); // bajamos un poco la resolución
p.RenderingOptions.UseNewImagingEngine = true;
p.Process(doc.Pages[idx], imageStream); // esta instrucción demora cerca de 1 segundo
//System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream);
//ScaleImage(image, 1138, 760, path_base + fileMask + "-" + idx + ".png", out height, out Aratio);
//image.Dispose();
using (System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream))
{
//this scales the image and writes it to a disc
ScaleImage(image, 1138, 760, path_base + fileMask + "-" + idx + ".png", out height, out Aratio);
}
if (idx == 1) { fields = CheckFields(doc, idx, "image" + fileMask + "-" + idx + ".png", fields, Convert.ToDouble(Aratio)); }
po.pageNumber = idx;
po.pageName = "image" + fileMask + "-" + idx + ".png";
po.Height = height;
po.Ratio = Aratio;
lpages.Add(po);
}
});
文件写入
protected static void ScaleImage(System.Drawing.Image image, int maxWidth, int maxHeight, string path, out string height, out string Aratio)
{
var ratio = (double)maxWidth / image.Width;
Aratio = ratio.ToString();
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
height = newHeight.ToString();
//var newImage = new Bitmap(newWidth, newHeight);
using (var newImage = new Bitmap(newWidth, newHeight))
{
Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
using (var bmp = new Bitmap(newImage))
{
bmp.Save(path, ImageFormat.Png);
}
}
//newImage.Dispose();
}
清理过程(西班牙语中的变量名)
private static int _segundos = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PeriodoLimpiezaTemp"].ToString());
public static void LimpiarTemporales(string rutaTemporal = "", string mask = "*", int? segundos = null)
{
int time = segundos ?? _segundos;
System.Threading.Tasks.Task.Run(
() =>
{
rutaTemporal = string.IsNullOrEmpty(rutaTemporal) ? Path.GetTempPath() : rutaTemporal;
var dInfo = new DirectoryInfo(rutaTemporal);
var files = dInfo.GetFiles(mask);
foreach (var file in files)
{
var dif = (DateTime.Now - file.CreationTime);
if (dif.TotalSeconds >= time )
{
try
{ //Intenta el eliminar los temporales. Si no puede sigue de largo.
file.Delete();
}
catch
{
//do nothing. Just in case some file it's been used by another process. I don't care if any file is left here, the next run may delete it.
}
}
};
});
}
我想在Global.asax中使用它的地方
protected void Session_End()
{
int segundos = 14400;
LimpiarTemporales(segundos);
}
protected void Application_End()
{
LimpiarTemporales();
}
创建临时文件的最佳方法是什么? (考虑到我必须在渲染之前创建它们……)
管理删除的最佳方法是什么?
欢迎任何建议