【问题标题】:File download in chunks in http-context response C#在http-context响应C#中分块下载文件
【发布时间】:2018-11-16 11:14:13
【问题描述】:

我有以下情况。

客户端向 Server-1 发送文件下载请求 Server-1 向 Server-2 发送文件请求。

为了完成这项工作,我需要创建一种机制,一旦客户端向 Server-1 发送请求,Server-1 将向 Server-2 请求,Server-2 将文件作为响应输出流以块的形式发送。 Server-1 会不断地向客户端浏览器发送这个文件块,因为它会不断地从 server-2 接收。

我已经完成了如下代码,理论上它看起来不错,但仍然无法正常工作。 它没有在客户端浏览器中下载整个文件,似乎最后一个块没有传输到 Server-1 或者它没有从 Server-1 下载到客户端浏览器

Server-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();
        }
    }

Server-2 代码(Server-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();
                }
            }
        }
    }

请帮我解决这个问题。

【问题讨论】:

  • 可以分享一下你试过的代码吗?
  • 您要查找的关键字是chunked
  • 如果我分块发送响应然后将其下载到客户端浏览器是否可行? @Jimbot
  • 是的,它在 http 1.1 中,所以几乎所有的浏览器都兼容

标签: c# webrequest httpwebresponse http-chunked responsestream


【解决方案1】:

这是可能的和可行的。我会给出一个伪程序让你理解整体思路。

服务器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

【讨论】:

  • 是的,我理解这个概念。但是如果我需要在 server-1 结束当前响应会发生什么,因为在我结束响应之前,它不会被下载到客户端浏览器中。
  • 感谢您确认它是可行的:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 2022-06-25
  • 1970-01-01
  • 2017-12-19
  • 2021-01-07
  • 1970-01-01
  • 2010-12-20
相关资源
最近更新 更多