前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >附件下载显示进度条

附件下载显示进度条

原创
作者头像
学以致用丶
发布2022-06-29 09:25:11
1.8K0
发布2022-06-29 09:25:11
举报
文章被收录于专栏:学习记录的专栏

问题

使用axios进行流处理文件下载的过程中,如果文件比较大,就需要等待整个文件流都下载到内存中才会弹出浏览器的下载文件保存对话框,这种方式在下载小文件的场景没什么问题,但是遇到大文件,一方面是浏览器的下载保存对话框半天都不会响应客户,这样体验不是很好;另外一方面是受到客户端内存的限制。

解决办法:

代码语言:javascript
复制
function downloadFileByUrl() {
    var url = '/api/common/downloadFile?xxxx.srt'
    fetch(url, {
        method: 'GET',
        cache: 'no-cache'
    }).then(res => {
        const fileStream = streamSaver.createWriteStream('文件名.mp4', {
            size: res.headers.get("content-length")
        })
        const readableStream = res.body
        // more optimized
        if (window.WritableStream && readableStream.pipeTo) {
            return readableStream.pipeTo(fileStream)
                .then(() => console.log('done writing'))
        }
        window.writer = fileStream.getWriter()

        const reader = res.body.getReader()
        const pump = () => reader.read()
            .then(res => res.done
                ? window.writer.close()
                : window.writer.write(res.value).then(pump))

        pump()
    })
}

引用js附件

代码语言:javascript
复制
<script src="@Url.Content("~/")Static/js/streamSaver.js"></script>

需要修改streamSaver.js文件面的内容,配置成

代码语言:javascript
复制
//if you decide to host mitm + sw yourself
streamSaver.mitm ='https://example.com/custom_mitm.html'

具体参考streamSaver.js

StreamSaver

下载附件后端的几种方法:

代码语言:javascript
复制
/// <summary>
/// 下载附件
/// </summary>
/// <param name="id">附件ID</param>
/// <returns></returns>
[HttpGet, Route("api/file/download"), AllowAnonymous]
public HttpResponseMessage Download(Guid id)
{
    HttpResponseMessage res = new HttpResponseMessage(HttpStatusCode.OK);

    //附件路径
    string fileNames= AppendixHelper.GetFileName(id, AppendixFormat.档案原始稿);
    if (fileNames.Count == 0)
    {
        throw new Exception(MessageCode.CM0000);
    }
    else
    {
        res.Content = new StreamContent(new FileStream(fileNames[0], FileMode.Open));
        res.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    }

    return res;
}

方法二:

代码语言:javascript
复制
/// <summary>
/// 
/// </summary>
/// <param name="attachmentId"></param>
/// <returns></returns>
[HttpGet, HttpHead, Route("api/downloadT/{attachmentId}"), AllowAnonymous]
public IHttpActionResult DownloadServerT2(Guid? attachmentId)
{
    if (!attachmentId.HasValue)
    {
        return ResponseMessage(new HttpResponseMessage(HttpStatusCode.BadRequest));
    }
    HttpResponseMessage res = new HttpResponseMessage(HttpStatusCode.OK);

   
    var fileLength = 2000;//文件大小
    var fileName = "http://xxxxxx/xxxxxx.pdf";//文件地址

    HttpResponseMessage response = new HttpResponseMessage();
    string MimeType = "application/octet-stream";
    long speed = 1024 * 100;
    long packSize = 1024 * 10;
    int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);//毫秒数:读取下一数据块的时间间隔
    ContentInfo contentInfo = GetContentInfoFromRequest(this.Request, fileLength);
    Action<Stream, HttpContent, TransportContext> pushContentAction = (outputStream, content, context) =>
    {
        try
        {
            int length = Convert.ToInt32((fileLength - 1) - contentInfo.From) + 1;
            while (length > 0 && packSize > 0)
            {
                WebClient wc = new WebClient();
                wc.BaseAddress = fileName;
                byte[] fdfs;
                fdfs = wc.DownloadData(wc.BaseAddress);

                outputStream.Write(fdfs, 0, fdfs.Length);
                contentInfo.From = contentInfo.From + fdfs.Length;
                length -= fdfs.Length;
                if (sleep > 1)
                {
                    Thread.Sleep(sleep);
                }
            }
        }
        catch (HttpException ex)
        {
            throw ex;
        }
        finally
        {
            outputStream.Close();
        }
    };
    response.Content = new PushStreamContent(pushContentAction, new MediaTypeHeaderValue(MimeType));
    var browser = String.Empty;
    if (Request.Headers.UserAgent != null)
    {
        browser = Request.Headers.UserAgent.ToString().ToUpper();
    }
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") // 设置头部其他内容特性, 文件名
    {
        FileName = browser.Contains("FIREFOX") ? fileName : HttpUtility.UrlEncode(fileName)
    };

    return ResponseMessage(response);
}

方法三:

代码语言:javascript
复制
/// <summary>
/// 
/// </summary>
/// <param name="FileName">文件名称</param>
/// <param name="FilePath">文件路径</param>
public void DownLoad(string FileName, string FilePath)
{
    string result = string.Empty;
    WebClient wc = new WebClient();
    wc.BaseAddress = FilePath;
    byte[] bytes;
    bytes = wc.DownloadData(wc.BaseAddress);
    Response.ContentType = "application/octet-stream";
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", HttpUtility.UrlEncode(
    FileName), System.Text.Encoding.UTF8));
    MemoryStream ms = new MemoryStream(bytes); 
    ms.WriteTo(Response.OutputStream); 
    ms.Dispose(); 
    ms.Close();
}

方法四:

代码语言:javascript
复制
/// <summary>
/// 下载实时返回下载进度
/// </summary>
/// <param name="URL">下载地址</param>
/// <param name="filename">本地存储地址</param>
public void DownloadFileData2(string URL, string filename)
{
    float percent = 0;
    try
    {
        HttpWebRequest Myrq = (HttpWebRequest)HttpWebRequest.Create(URL);
        HttpWebResponse myrp = (HttpWebResponse)Myrq.GetResponse();
        long totalBytes = myrp.ContentLength, totalDownloadedByte = 0;
        Stream st = myrp.GetResponseStream();


        using (MemoryStream ms = new MemoryStream())
        {
            HttpResponse response = System.Web.HttpContext.Current.Response;
            response.Clear();

            response.Charset = "GB2312";
            response.ContentType = "application/msword";
            byte[] by = new byte[1024];
            int osize = st.Read(by, 0, (int)by.Length);
            while (osize > 0)
            {
                totalDownloadedByte = osize + totalDownloadedByte;
                ms.Write(by, 0, osize);
                osize = st.Read(by, 0, (int)by.Length);
                percent = (float)totalDownloadedByte / (float)totalBytes * 100;//当前位置
            }
            st.Close();
            System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename=" + filename));
            response.ContentEncoding = System.Text.Encoding.Unicode;
            ms.WriteTo(response.OutputStream);
            ms.Close();
        }
        HttpContext.Current.Response.End();

    }
    catch (System.Exception)
    {
        throw;
    }
}

文件先保存在下载

代码语言:javascript
复制
//string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".doc";
                using (MemoryStream ms = new MemoryStream())
                {
                    HttpResponse response = System.Web.HttpContext.Current.Response;
                    response.Clear();

                    response.Charset = "GB2312";
                    response.ContentType = "application/msword";
                    doc.Save(ms, SaveFormat.Doc);
                    System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename=" + filename));
                    response.ContentEncoding = System.Text.Encoding.Unicode;
                    ms.WriteTo(response.OutputStream);
                    ms.Close();
                }
                HttpContext.Current.Response.End();

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档