Скопируйте файл с удаленного сервера в клиентский браузер через мой сервер, не записывая весь файл на диск или в память
Это сценарий.
На удаленном файловом сервере есть файл (скажем, у меня есть файл, размещенный на DropBox)
Я хочу предложить этот файл для загрузки в моем веб-приложении (C# asp.net 4.0)
Я хочу, чтобы скрыть местоположение на 100% от исходного файла (я хочу, чтобы он появился из моего сервера).
Я не хочу записывать этот файл в память или на диск на моем сервере.
Я предполагал, что захочу использовать поток для потокового копирования. пример
Stream inputStream = response.GetResponseStream();
inputStream.CopyTo(Response.OutputStream, 4096);
inputStream.Flush();
Response.Flush();
Response.End();
Это, однако, копирует весь поток в память перед записью его в браузер клиента. Любые идеи будут потрясающими.
Мне нужно, чтобы мой сервер в основном действовал как прокси и защищал исходное местоположение файла
Спасибо за любую помощь.
2 ответа
Пока я не вижу причин, почему CopyTo
будет считывать весь поток в памяти (поскольку нигде нет промежуточного потока), вы можете написать одну и ту же копию вручную, чтобы убедиться, что она ведет себя так, как вы хотите.
Подумайте об использовании Async версий для чтения / записи, и если вы можете использовать async
/awit
из C# 4.0, чтобы сделать код читабельным.
Старый способ: асинхронная потоковая обработка, новые способы асинхронного файлового ввода-вывода
Следующий код - это то, чем я закончил (размер буфера изменится в рабочей среде). Он получает файл из URL-адреса и начинает передавать его по частям клиенту через мой сервер. То, что мне понадобилось, чтобы понять, - это очистка Ответа после написания каждого куска.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(digitalAsset.FullFilePath);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + digitalAsset.FileName);
Stream inputStream = response.GetResponseStream();
byte[] buffer = new byte[512];
int read;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, read);
Response.Flush();
}
Response.End();
}
Это может передавать файл любого размера через мой сервер, не дожидаясь, пока мой сервер сначала сохранит его в памяти или на диске. Реальное преимущество заключается в том, что он использует очень мало памяти, поскольку сохраняется только буферизованный кусок. Для клиента загрузка начинается мгновенно. (это, вероятно, очевидно для большинства, но для новичка это было очень здорово), поэтому мы одновременно скачиваем файл из одного места и загружаем его в другое, используя сервер в качестве прокси-сервера.