这里我在Azure上托管的ASP.NET MVC3上有一个简单的功能。
- 第一步:用户上传图片
- 第二步:用户裁剪上传的图片
- 第三:系统保存裁剪后的图片,删除作为上传原始图片的临时文件
我现在面临的问题是:临时文件存储在哪里?
我在某个地方尝试了windows系统,或者在LocalResources上:问题是这些资源是每个实例的,所以不能保证实例上显示要裁剪的图片的代码与保存临时文件的实例上的代码相同。
你知道这个临时文件的问题吗?
- 通常,文件在删除之前只存在一段时间
- 临时文件需要独立于实例
- 更好的是,文件可以有一些过期设置(例如1H)来删除自己,以防代码在某个地方崩溃
好。所以,你所追求的基本上是共享存储但过期的东西。亚马逊刚刚宣布了一个相当不错的设置,称为对象过期(https://forums.aws.amazon.com/ann.jspa?annID=1303)。不幸的是,Windows Azure存储还没有这样的东西,但这并不意味着我们不能想出其他方法;甚至想出了一个更好(更具成本效益)的方法。
你说它需要独立于实例,这意味着使用本地临时驱动器是不可能的。正如其他人所说,我最初倾向于Blob存储,但你会在那里进行清理。如果您使用的是大映像(>1MB)或低吞吐量(<100rps),那么我认为Blob存储是唯一的选择。如果您使用的是较小的图像和高吞吐量,那么blob存储的交易成本将开始真正增加(我很快就会发布一份白皮书,其中显示了一些对此的建模,但下面是一些快速的想法)。
对于图像小、吞吐量高的场景,更好的选择可能是使用Windows Azure缓存作为临时存储区域。乍一看,它会贵得令人瞠目;基于每GB(缓存为110GB/月,存储为12c/GB)。但是,对于存储,您的交易是付费的,而对于Cache,它们是"免费的"。(配额如下:http://msdn.microsoft.com/en-us/library/hh697522.aspx#C_BKMK_FAQ8)这真的可以加起来;例如,使用缓存以1500rps的系统吞吐量保持20分钟的100kb临时文件每月约为1000美元,而存储事务每月约为15000美元。
Azure缓存方法非常值得考虑,但是,为了确保它是我真正想知道的"最佳"方法;
- 图像大小
- 每小时吞吐量
- 关于裁剪过程中客户端与服务器的实际交互的更多细节?这是一个互动过程吗?用户将把iamage拉到浏览器中并进行视觉裁剪?还是它只是一种简单的作物
以下是我认为可能的方法:
- 用户上传图片
- 您的代码将其保存到一个blob中,并有一些数据后端来了解用户会话和上传图像之间的关系(将其标记为临时图像)
- 在裁剪用户界面中显示图像
-
当用户在客户端上完成裁剪时:
4.1.从斑点中检索原件
4.2.根据用户发送的数据进行裁剪
4.3.从blob中删除原始文件,并在步骤2 中使用的数据后端中删除记录
4.4.将最终结果保存到另一个blob(最终blob)。
并让一个后台进程检查数据后端中的"过期"临时图像(在步骤2中使用),以删除数据后端中图像和记录。
请注意,即使在WebRole中,您仍然有RoleEntryPoint子代,并且您仍然可以覆盖Run方法。在Run()方法中实现无限循环(该方法应never退出!),您可以每隔N秒检查是否有任何可删除的内容(取决于Run()中的Thread.Sleep()。
您可以使用Azure blob存储。看看这个教程。
Under sample将为您提供帮助。https://code.msdn.microsoft.com/How-to-store-temp-files-in-d33bbb10
你在Azure中有两种临时文件。1,可以使用Path.GetTempPath和Path.GetTempFilename()函数作为临时文件名2,你可以使用Azure blob来模拟它。
private long TotalLimitSizeOfTempFiles = 100 * 1024 * 1024;
private async Task SaveTempFile(string fileName, long contentLenght, Stream inputStream)
{
try
{
//firstly, we need check the container if exists or not. And if not, we need to create one.
await container.CreateIfNotExistsAsync();
//init a blobReference
CloudBlockBlob tempFileBlob = container.GetBlockBlobReference(fileName);
//if the blobReference is exists, delete the old blob
tempFileBlob.DeleteIfExists();
//check the count of blob if over limit or not, if yes, clear them.
await CleanStorageIfReachLimit(contentLenght);
//and upload the new file in this
tempFileBlob.UploadFromStream(inputStream);
}
catch (Exception ex)
{
if (ex.InnerException != null)
{
throw ex.InnerException;
}
else
{
throw ex;
}
}
}
//check the count of blob if over limit or not, if yes, clear them.
private async Task CleanStorageIfReachLimit(long newFileLength)
{
List<CloudBlob> blobs = container.ListBlobs()
.OfType<CloudBlob>()
.OrderBy(m => m.Properties.LastModified)
.ToList();
//get total size of all blobs.
long totalSize = blobs.Sum(m => m.Properties.Length);
//calculate out the real limit size of before upload
long realLimetSize = TotalLimitSizeOfTempFiles - newFileLength;
//delete all,when the free size is enough, break this loop,and stop delete blob anymore
foreach (CloudBlob item in blobs)
{
if (totalSize <= realLimetSize)
{
break;
}
await item.DeleteIfExistsAsync();
totalSize -= item.Properties.Length;
}
}