Загрузка файла кусками в http-контексте ответа C # - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть сценарий ниже.

Клиент отправляет запрос на сервер-1 для загрузки файла Сервер-1 отправляет запрос на Сервер-2 для файла.

Чтобы сделать эту работу, мне нужно создать механизм, в котором после отправки клиентом запроса на Сервер-1 Сервер-1 будет запрашивать Сервер-2, который будет отправлять файл как поток вывода ответа в виде фрагментов. Сервер-1 будет непрерывно отправлять куски этого файла в браузер клиента, поскольку он продолжает получать от сервера-2.

Я сделал код, как показано ниже, теоретически он выглядит хорошо, но все равно он не работает. Он не загружает весь файл в браузер клиента, похоже, что последний кусок не передается на сервер-1 или он не загружается в браузер клиента с сервера-1

Код сервера-1 (где клиент запрашивает загрузку файла)

    private void ProccesBufferedResponse(HttpWebRequest webRequest, HttpContext context)
    {
        char[] responseChars = null;
        byte[] buffer = null;

        if (webRequest == null)
            logger.Error("Request string is null for Perfios Docs Download at ProccesBufferedResponse()");

        context.Response.Buffer = false;
        context.Response.BufferOutput = false;
        try
        {

            WebResponse webResponse = webRequest.GetResponse();
            context.Response.ContentType = "application/pdf";
            context.Response.AddHeader("Content-disposition", webResponse.Headers["Content-disposition"]);

            StreamReader responseStream = new StreamReader(webResponse.GetResponseStream());
            while (!responseStream.EndOfStream)
            {
                responseChars = new char[responseStream.ToString().ToCharArray().Length];
                responseStream.Read(responseChars, 0, responseChars.Length);
                buffer = Encoding.ASCII.GetBytes(responseChars);

                context.Response.Clear();
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
                context.Response.Flush();

            }

        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            context.Response.Flush();
            context.Response.End();
        }
    }

Код сервера-2 (куда сервер-1 отправит запрос на файл)

    private void DownloadInstaPerfiosDoc(int CompanyID, string fileName, string Foldertype)
    {
        string folderPath;
        string FilePath;
        int chunkSize = 1024;
        int startIndex = 0;
        int endIndex = 0;
        int length = 0;
        byte[] bytes = null;
        DirectoryInfo dir;

        folderPath = GetDocumentDirectory(CompanyID, Foldertype);
        FilePath = folderPath + "\\" + fileName;
        dir = new DirectoryInfo(folderPath);
        HttpContext.Current.Response.Buffer = false;
        HttpContext.Current.Response.BufferOutput = false;

        if (dir.Exists && dir.GetFiles().Length > 0)
        {
            foreach (var file in dir.GetFiles(fileName))
            {
                FilePath = folderPath + "\\" + file.Name;
                FileStream fsReader = new FileStream(FilePath, FileMode.Open, FileAccess.Read);

                HttpContext.Current.Response.ContentType = "application/pdf";
                HttpContext.Current.Response.AddHeader("Content-disposition", string.Format("attachment; filename = \"{0}\"", fileName));

                int totalChunks = (int)Math.Ceiling((double)fsReader.Length / chunkSize);
                for (int i = 0; i < totalChunks; i++)
                {
                    startIndex = i * chunkSize;

                    if (startIndex + chunkSize > fsReader.Length)
                        endIndex = (int)fsReader.Length;
                    else
                        endIndex = startIndex + chunkSize;

                    length = (int)endIndex - startIndex;
                    bytes = new byte[length];
                    fsReader.Read(bytes, 0, bytes.Length);
                    HttpContext.Current.Response.Clear();
                    HttpContext.Current.Response.OutputStream.Write(bytes, 0, bytes.Length);
                    HttpContext.Current.Response.Flush();
                }
            }
        }
    }

Пожалуйста, помогите мне решить эту проблему.

1 Ответ

0 голосов
/ 16 ноября 2018

Это возможно и осуществимо. Я дам вам псевдо-процедуру, чтобы вы поняли общую идею.

Сервер1

download action gets hit
create a request to server2
get the response stream of your server2 request
read the response stream in desired chunk sizes until it's consumed completely
write each chunk (as soon as you read) to current response stream

Сервер2

download action gets hit
write your stream onto your current response stream however you like
...