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);
    }
}