Web API下载锁定文件

JBu*_*uus 4 c# asp.net asp.net-mvc-4 asp.net-web-api

我遇到一个WebAPI方法的小问题,当用户调用方法的路由时,该方法会下载文件.

方法本身很简单:

public HttpResponseMessage Download(string fileId, string extension)
{
    var location = ConfigurationManager.AppSettings["FilesDownloadLocation"];
    var path = HttpContext.Current.Server.MapPath(location) + fileId + "." + extension;

    var result = new HttpResponseMessage(HttpStatusCode.OK);
    var stream = new FileStream(path, FileMode.Open);
    result.Content = new StreamContent(stream);
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    return result;
}
Run Code Online (Sandbox Code Playgroud)

该方法按预期工作 - 我第一次调用它.传输文件,我的浏览器开始下载文件.

但是 - 如果我从我自己的计算机或任何其他计算机再次调用相同的URL - 我收到一条错误消息:

该进程无法访问文件'D:\ ...\App_Data\pdfs\test-file.pdf',因为它正由另一个进程使用.

这个错误持续了大约一分钟 - 然后我可以再次下载文件 - 但只能一次 - 然后我必须等待一分钟左右,直到文件解锁.

请注意我的文件相当大(100-800 MB).

我在方法中遗漏了什么吗?它似乎流文件锁定文件一段时间或类似的东西?

谢谢 :)

Fab*_*NET 7

这是因为您的文件被第一个流锁定,您必须指定一个FileShare,允许它由多个流打开:

public HttpResponseMessage Download(string fileId, string extension)
{
    var location = ConfigurationManager.AppSettings["FilesDownloadLocation"];
    var path = HttpContext.Current.Server.MapPath(location) + fileId + "." + extension;

    var result = new HttpResponseMessage(HttpStatusCode.OK);
    var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
    result.Content = new StreamContent(stream);
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    return result;
}
Run Code Online (Sandbox Code Playgroud)

像这样你允许多个流打开这个文件只读.

请参阅有关该构造函数重载的MSDN文档.

  • @JBuus欢迎你.文件流将在内容流发布后立即处理,事实上应该是在客户端完成读取响应时. (2认同)