我有一个异步控制器方法,该方法在调用时会做一些繁重的工作,创建文件夹,压缩文件并将其组合成最终的归档文件,该归档文件通过下载返回给客户端。问题是,完成后我需要删除文件,但是在删除过程中出现错误:
该进程无法访问文件'Archive.zip',因为它正在被另一个进程使用。
我了解问题所在,但我不知道该如何解决。
以下是一些代码段:
首先,我创建了一个自定义过滤器:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class DeleteFileAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext filterContext)
{
// Delete file
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
var path = new DirectoryInfo(Library.Utilities.Files.MapPath("~/archives"));
foreach (var dir in path.GetDirectories())
{
dir.Delete(true);
}
base.OnActionExecuted(filterContext);
}
}
这是我的主控制器入口点,我使用该自定义过滤器进行了修饰:
[DeleteFile]
[HttpGet]
public async Task<IHttpActionResult> Download(string boardId, string boardName)
{
// I do a bunch of file related stuff, and then:
return new FileActionResult(boardName + ".zip", zipPath);
}
这是我的FileActionResult
课:
public class FileActionResult : IHttpActionResult
{
public FileActionResult(string filename, string path)
{
Filename = filename;
Path = path;
}
public string Filename { get; }
public string Path { get; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpContext.Current.Response.Clear();
var response = new HttpResponseMessage {Content = new StreamContent(File.OpenRead(Path))};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-zip-compressed");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Filename
};
return Task.FromResult(response);
}
}
我认为通过在删除文件之前刷新并结束动作过滤器中的响应会有所帮助,但这没有帮助。
答案 0 :(得分:0)
尝试处理流内容:
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpContext.Current.Response.Clear();
HttpResponseMessage response = null;
using (var stream = new File.OpenRead(path))
{
response = new HttpResponseMessage { Content = new StreamContent(stream)};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-zip-compressed");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Filename
};
}
return Task.FromResult(response);
}