ASP.NET WebForm 下载文件,兼容各个浏览器,下载文件名无乱码

protected void btnDownload_Click(object sender, EventArgs e)
{
    string webPath = Request.QueryString["filename"];
    string filePath = Server.MapPath(webPath);//路径
    FileInfo fileInfo = new FileInfo(filePath);
    string fileName = fileInfo.Name; //客户端保存的文件名

    if (fileInfo.Exists == true)
    {
        const long ChunkSize = 102400;//100K 每次读取文件,只读取100K,这样可以缓解服务器的压力
        byte[] buffer = new byte[ChunkSize];

        Response.Clear();
        System.IO.FileStream iStream = System.IO.File.OpenRead(filePath);
        long dataLengthToRead = iStream.Length;//获取下载的文件总大小
        Response.ContentType = "application/octet-stream";

        if (Request.UserAgent.ToLower().IndexOf("msie") > -1 )
        {   
            Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName));
        }
        else if (Request.UserAgent.ToLower().IndexOf("firefox") > -1)
        {
            //为了向客户端输出空格,需要在当客户端使用 Firefox 时特殊处理     
            Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        }
        else if (Request.UserAgent.ToLower().IndexOf("edge") > -1) // edeg浏览器
        {
            Response.AddHeader("Content-Disposition", "attachment;filename=" + ToHexString(fileName));
        }
        else
        {
            Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
        }

        while (dataLengthToRead > 0 && Response.IsClientConnected)
        {
            int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//读取的大小
            Response.OutputStream.Write(buffer, 0, lengthRead);
            Response.Flush();
            dataLengthToRead = dataLengthToRead - lengthRead;
        }
        Response.Close();
    }

}

/// <summary> 
/// 为字符串中的非英文字符编码 
/// </summary> 
/// <param name="s"></param> 
/// <returns></returns> 
public string ToHexString(string s)
{
    char[] chars = s.ToCharArray();
    StringBuilder builder = new StringBuilder();
    for (int index = 0; index < chars.Length; index++)
    {
        bool needToEncode = NeedToEncode(chars[index]);
        if (needToEncode)
        {
            string encodedString = ToHexString(chars[index]);
            builder.Append(encodedString);
        }
        else
        {
            builder.Append(chars[index]);
        }
    }
    return builder.ToString();
}
/// <summary> 
///指定 一个字符是否应该被编码 
/// </summary> 
/// <param name="chr"></param> 
/// <returns></returns> 
private bool NeedToEncode(char chr)
{
    string reservedChars = "$-_.+!*'(),@=&";
    if (chr > 127)
        return true;
    if (char.IsLetterOrDigit(chr) || reservedChars.IndexOf(chr) >= 0)
        return false;
    return true;
}
/// <summary> 
/// 为非英文字符串编码 
/// </summary> 
/// <param name="chr"></param> 
/// <returns></returns> 
private string ToHexString(char chr)
{
    UTF8Encoding utf8 = new UTF8Encoding();
    byte[] encodedBytes = utf8.GetBytes(chr.ToString());
    StringBuilder builder = new StringBuilder();
    for (int index = 0; index < encodedBytes.Length; index++)
    {
        builder.AppendFormat("%{0}", Convert.ToString(encodedBytes[index], 16));
    }
    return builder.ToString();
}
本文为“技术点滴”的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注