Потоковая обработка больших изображений с помощью ASP.Net Webapi
Мы пытаемся вернуть большие файлы изображений с помощью ASP.Net WebApi и используя следующий код для потоковой передачи байтов клиенту.
public class RetrieveAssetController : ApiController
{
// GET api/retrieveasset/5
public HttpResponseMessage GetAsset(int id)
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
string filePath = "SomeImageFile.jpg";
MemoryStream memoryStream = new MemoryStream();
FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
memoryStream.Write(bytes, 0, (int)file.Length);
file.Close();
httpResponseMessage.Content = new ByteArrayContent(memoryStream.ToArray());
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
}
}
Приведенный выше код работает нормально, но некоторые из файлов, с которыми мы имеем дело, могут иметь размер 2 ГБ и выше, что приводит к таймаутам соединения. В прошлом мы использовали код, похожий на предыдущий (с использованием HttpHandlers), чтобы передать ответ на поток ответов, чтобы поддерживать соединение с успехом.
byte[] b = new byte[this.BufferChunkSize];
int byteCountRead = 0;
while ((byteCountRead = stream.Read(b, 0, b.Length)) > 0)
{
if (!response.IsClientConnected) break;
response.OutputStream.Write(b, 0, byteCountRead);
response.Flush();
}
Как мы можем использовать подобный метод с использованием новой модели программирования WebAPI, показанной ранее?
Заранее благодарю
Ответы
Ответ 1
Да, вы можете использовать PushStreamContent
. И если вы объедините его с асинхронным выполнением (usin i.e. async lambdas), вы можете получить еще более эффективные результаты.
В этом месяце я написал блог об этом подходе - http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/.
В примере используется видеофайл, принцип тот же - сбрасывание байтов данных клиенту.
Ответ 2
Поток непосредственно из файла с помощью StreamContent
(слишком нового?). Подобно API-интерфейсу Web API конвертирует MemoryStream в StreamContent
httpResponseMessage.Content = new StreamContent(file);