我与溪流混淆,返回价值和处置。即我使用Stream并希望从方法返回流。下一个代码:
public async Task<HttpResponseMessage> GetOverlayAsync(string fileUrl, string language, string strOCR)
{
HttpResponseMessage result = Request.CreateResponse(HttpStatusCode.OK);
using (var stream = new FileStream(@"D:\\_forTest.jpg", FileMode.Open))
{
length = stream.Length;
result.Content = new StreamContent(stream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = Path.GetFileName("_forTest.jpg");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentLength = length;
return result;
}
}
和
public async Task<HttpResponseMessage> GetOverlayAsync(string fileUrl, string language, string strOCR)
{
long length = 0;
HttpResponseMessage result = Request.CreateResponse(HttpStatusCode.OK);
using (var stream = new FileStream(@"D:\\_forTest.jpg", FileMode.Open))
{
length = stream.Length;
result.Content = new StreamContent(stream);
}
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = Path.GetFileName("_forTest.jpg");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentLength = length;
return result;
}
返回504状态代码:
ReadResponse()失败:服务器未返回完整的响应 对于这个请求。服务器返回0个字节。
所以,据我所知,当我们从方法出去时,流被处理
如果我根本不打电话给Dispose:
public async Task<HttpResponseMessage> GetOverlayAsync(string fileUrl, string language, string strOCR)
{
long length = 0;
HttpResponseMessage result = Request.CreateResponse(HttpStatusCode.OK);
var stream = new FileStream(@"D:\\_forTest.jpg", FileMode.Open);
length = stream.Length;
result.Content = new StreamContent(stream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = Path.GetFileName("_forTest.jpg");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentLength = length;
return result;
}
有时我得到该文件被另一个进程阻止。如何正确使用?
答案 0 :(得分:2)
一些背景知识 一般来说,如果您希望流式传输文件内容,那么您要执行的操作是从文件流中读取并写入HTTP响应的输出流。 例如:
using (var source = new FileStream(...))
{
byte[] buffer = new byte[4096];
int byteCount;
while ((byteCount = await source.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await output.WriteAsync(buffer, 0, byteCount);
}
}
现在,在您的特定情况下,您正在使用框架/模式,要求您将内容传递给您的内容,而不是让您自己写入输出。在这种情况下,您被迫将处理流的责任转移到处理程序方法的调用者。
<强>具体细节:强> 如果您的问题是文件被锁定,那么您可以在打开流时允许共享读/写访问:
var stream = new FileStream(@"D:\\_forTest.jpg", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
这将允许其他进程在您读取文件时对该文件具有读写权限。
编辑:如@Evk所述,更安全的选择是仅与读者共享访问权限(尝试打开文件进行写入将被拒绝): var stream = new FileStream(@"D:\\_forTest.jpg", FileMode.Open, FileAccess.Read, FileShare.Read);
<强>改进:强> 如果你的文件适合内存,那么mem-cache而不是直接从磁盘流式传输是明智的。如果您有数千个同时请求来获取此文件,您的磁盘将成为一个巨大的瓶颈。使用具有保留/到期策略的缓存,并在缓存未命中时读取和缓存整个文件。这样,您还可以最小化打开文件句柄的窗口(打开,线性I / O读取,关闭;非常快)。