Azure Web App 临时文件清理责任
Azure Web App Temp file cleaning responsibility
在我的一个 Azure Web App Web API 应用程序中,我在 Get 方法中使用此代码创建临时文件
string path = Path.GetTempFileName();
// do some writing on this file. then read
var fileStream = File.OpenRead(path);
// then returning this stream as a HttpResponseMessage response
我的问题是,在这样的托管环境中(不是在 VM 中),我需要自己清除那些临时文件吗?
Azure 本身不应该清除这些临时文件吗?
这些文件只有在您的站点重新启动时才会被清除。
如果您的站点 运行 以免费或共享模式运行,它只会为临时文件分配 300MB,因此如果您不清理,可能会 运行 退出。
如果您的站点处于基本或标准模式,则 space 的空间要大得多(大约 200GB!)。因此,如果 运行 未达到限制,您可能可以不清理而逃脱。最终,您的站点将重新启动(例如在平台升级期间),因此一切都会得到清理。
有关此主题的更多详细信息,请参阅 this page。
以下示例演示了如何在 Azure 中保存临时文件,包括 Path 和 Bolb。
文档在这里:https://code.msdn.microsoft.com/How-to-store-temp-files-in-d33bbb10
代码点这里:https://github.com/Azure-Samples/storage-blob-dotnet-store-temp-files/archive/master.zip
下面是bolb代码的核心逻辑:
private long TotalLimitSizeOfTempFiles = 100 * 1024 * 1024;
private async Task SaveTempFile(string fileName, long contentLenght, Stream inputStream)
{
try
{
await container.CreateIfNotExistsAsync();
CloudBlockBlob tempFileBlob = container.GetBlockBlobReference(fileName);
tempFileBlob.DeleteIfExists();
await CleanStorageIfReachLimit(contentLenght);
tempFileBlob.UploadFromStream(inputStream);
}
catch (Exception ex)
{
if (ex.InnerException != null)
{
throw ex.InnerException;
}
else
{
throw ex;
}
}
}
private async Task CleanStorageIfReachLimit(long newFileLength)
{
List<CloudBlob> blobs = container.ListBlobs()
.OfType<CloudBlob>()
.OrderBy(m => m.Properties.LastModified)
.ToList();
long totalSize = blobs.Sum(m => m.Properties.Length);
long realLimetSize = TotalLimitSizeOfTempFiles - newFileLength;
foreach (CloudBlob item in blobs)
{
if (totalSize <= realLimetSize)
{
break;
}
await item.DeleteIfExistsAsync();
totalSize -= item.Properties.Length;
}
}
也许如果您扩展 FileStream,您可以重写 dispose 并在调用 dispose 时删除它?这就是我现在解决它的方式。如果我错了请告诉我。
/// <summary>
/// Create a temporary file and removes its when the stream is closed.
/// </summary>
internal class TemporaryFileStream : FileStream
{
public TemporaryFileStream() : base(Path.GetTempFileName(), FileMode.Open)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
// After the stream is closed, remove the file.
File.Delete(Name);
}
}
在我的一个 Azure Web App Web API 应用程序中,我在 Get 方法中使用此代码创建临时文件
string path = Path.GetTempFileName();
// do some writing on this file. then read
var fileStream = File.OpenRead(path);
// then returning this stream as a HttpResponseMessage response
我的问题是,在这样的托管环境中(不是在 VM 中),我需要自己清除那些临时文件吗? Azure 本身不应该清除这些临时文件吗?
这些文件只有在您的站点重新启动时才会被清除。
如果您的站点 运行 以免费或共享模式运行,它只会为临时文件分配 300MB,因此如果您不清理,可能会 运行 退出。
如果您的站点处于基本或标准模式,则 space 的空间要大得多(大约 200GB!)。因此,如果 运行 未达到限制,您可能可以不清理而逃脱。最终,您的站点将重新启动(例如在平台升级期间),因此一切都会得到清理。
有关此主题的更多详细信息,请参阅 this page。
以下示例演示了如何在 Azure 中保存临时文件,包括 Path 和 Bolb。
文档在这里:https://code.msdn.microsoft.com/How-to-store-temp-files-in-d33bbb10
代码点这里:https://github.com/Azure-Samples/storage-blob-dotnet-store-temp-files/archive/master.zip
下面是bolb代码的核心逻辑:
private long TotalLimitSizeOfTempFiles = 100 * 1024 * 1024;
private async Task SaveTempFile(string fileName, long contentLenght, Stream inputStream)
{
try
{
await container.CreateIfNotExistsAsync();
CloudBlockBlob tempFileBlob = container.GetBlockBlobReference(fileName);
tempFileBlob.DeleteIfExists();
await CleanStorageIfReachLimit(contentLenght);
tempFileBlob.UploadFromStream(inputStream);
}
catch (Exception ex)
{
if (ex.InnerException != null)
{
throw ex.InnerException;
}
else
{
throw ex;
}
}
}
private async Task CleanStorageIfReachLimit(long newFileLength)
{
List<CloudBlob> blobs = container.ListBlobs()
.OfType<CloudBlob>()
.OrderBy(m => m.Properties.LastModified)
.ToList();
long totalSize = blobs.Sum(m => m.Properties.Length);
long realLimetSize = TotalLimitSizeOfTempFiles - newFileLength;
foreach (CloudBlob item in blobs)
{
if (totalSize <= realLimetSize)
{
break;
}
await item.DeleteIfExistsAsync();
totalSize -= item.Properties.Length;
}
}
也许如果您扩展 FileStream,您可以重写 dispose 并在调用 dispose 时删除它?这就是我现在解决它的方式。如果我错了请告诉我。
/// <summary>
/// Create a temporary file and removes its when the stream is closed.
/// </summary>
internal class TemporaryFileStream : FileStream
{
public TemporaryFileStream() : base(Path.GetTempFileName(), FileMode.Open)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
// After the stream is closed, remove the file.
File.Delete(Name);
}
}