C# 文件流下载相关整理

C# 流方式下载文件(hooyes提供)


private void Real(HttpResponse response, HttpRequest request)
        {
            if (File.Exists(request.PhysicalPath))
            {
                FileInfo file = new System.IO.FileInfo(request.PhysicalPath);
                response.Clear();
                response.AddHeader("Content-Disposition", "filename=" + file.Name);
                response.AddHeader("Content-Length", file.Length.ToString());
                string fileExtension = file.Extension.ToLower();
                switch (fileExtension)
                {
                    case ".mp3":
                        response.ContentType = "audio/mpeg3";
                        break;
                    case ".mpeg":
                        response.ContentType = "video/mpeg";
                        break;
                    case ".jpg":
                        response.ContentType = "image/jpeg";
                        break;
                    case ".bmp":
                        response.ContentType = "image/bmp";
                        break;
                    case ".gif":
                        response.ContentType = "image/gif";
                        break;
                    case ".doc":
                        response.ContentType = "application/msword";
                        break;
                    case ".css":
                        response.ContentType = "text/css";
                        break;
                    case ".html":
                        response.ContentType = "text/html";
                        break;
                    case ".htm":
                        response.ContentType = "text/html";
                        break;
                    case ".swf":
                        response.ContentType = "application/x-shockwave-flash";
                        break;
                    case ".exe":
                        response.ContentType = "application/octet-stream";
                        break;
                    case ".inf":
                        response.ContentType = "application/x-texinfo";
                        break;
                    default:
                        response.ContentType = "application/octet-stream";
                        break;
                }

                response.WriteFile(file.FullName);
                response.End();
            }
            else
            {
                response.Write("File Not Exists");
            }
        }
    }


写入后要判断文件是否存在,判断文件是否写入完成(是否被占用)


在程序中,我们经常遇到读写文件的情况,而这个时候该文件可能被其他程序占用,那么怎么判断文件是否被占用,从而友好的提示用户呢?

这里提供一个简单的办法,他就是尝试着去读该文件,如果失败,则说明文件被占用:

public static bool IsFileOpen(string filePath)
        {
            bool result = false;
            System.IO.FileStream fs=null;
            try
            {
                fs = File.OpenWrite(filePath);
                fs.Close();
            }
            catch (Exception ex)
            {
                result = true;
            }
            return result;//true 打开 false 没有打开
        }



MVC文件下载

public FileContentResult GetFile(int id)
{
  SqlDataReader rdr; byte[] fileContent = null; 
  string mimeType = "";string fileName = "";
  const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;";

  using (var conn = new SqlConnection(connect))
  {
    var qry = "SELECT FileContent, MimeType, FileName FROM FileStore WHERE ID = @ID";
    var cmd = new SqlCommand(qry, conn);
    cmd.Parameters.AddWithValue("@ID", id);
    conn.Open();
    rdr = cmd.ExecuteReader();
    if (rdr.HasRows)
    {
      rdr.Read();
      fileContent = (byte[])rdr["FileContent"];
      mimeType = rdr["MimeType"].ToString();
      fileName = rdr["FileName"].ToString();
    }
  }
  return File(fileContent, mimeType, fileName);
}

在View中最简单的使用来使用这个Action只需提供一个超链接:

<a href="/GetFile/1">Click to get file</a>

如果在数据库中存储的图片是图片类型,和使用超链接不同的是,我们通过指向Controller action的一个带有src属性的<image>标签来获取:

<img src="/GetFile/1" alt="My Image" />

下面再让我们来看看使用FilePathResult(用于从硬盘提取文件)是多简单的事:

public FilePathResult GetFileFromDisk()
{
  string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
  string fileName = "test.txt";
  return File(path + fileName, "text/plain", "test.txt");
}

而这也可以用过超链接提取:

<a href="/GetFileFromDisk">Click to get file</a>

而最后一个选择FileStreamResult也可以从磁盘中提取文件:

public FileStreamResult StreamFileFromDisk()
{
  string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
  string fileName = "test.txt";
  return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName);
}

FilePathResult和FileStreamResult的区别是什么?我们又该如何取舍呢?主要的区别是FilePathResult使用HttpResponse.TransmitFile来将文件写入Http输出流。这个方法并不会在服务器内存中进行缓冲,所以这对于发送大文件是一个不错的选择。他们的区别很像DataReader和DataSet的区别。于此同时, TransmitFile还有一个bug,这可能导致文件传到客户端一半就停了,甚至无法传送。而FileStreamResult在这方面就很棒了。比如说:返回Asp.net Chart 控件在内存中生成的图表图片,而这并不需要将图片存到磁盘中.



项目实例(生成pdf)


        // 生成账单HTML页面
        private string WriteHTMLFile(string strContent)
        {
            string createHtmlPath = System.Web.HttpContext.Current.Server.MapPath("/BillingFiles/DownloadFiles/");
            Encoding code = Encoding.GetEncoding("utf-8");
            // 读取模板文件
            string templateHTML = System.Web.HttpContext.Current.Server.MapPath("/BillingFiles/Template/BillingTemplate.html");
            StreamReader sr = null;
            StreamWriter sw = null;
            string str = string.Empty;
            try
            {
                sr = new StreamReader(templateHTML, code);
                str = sr.ReadToEnd();
            }
            catch (Exception ex)
            {
                log.Error("ReadFile Error:" + ex.Message + ex.InnerException + ex.StackTrace);
                sr.Close();
                return null;
            }

            string htmlFileName = "BillingDetail_" + currentUser.AccountId + DateTime.Now.ToString("_yyyyMMddHHmmss") + ".html";

            str = str.Replace("{body}", strContent);

            // 写HTML文件
            try
            {
                sw = new StreamWriter(createHtmlPath + htmlFileName, false, code);
                sw.Write(str);
                sw.Flush();
            }
            catch (Exception ex)
            {
                log.Error("WriteFile Error:" + ex.Message + ex.InnerException + ex.StackTrace);
                sw.Close();
                return null;
            }
            finally
            {
                sw.Close();
            }
            log.Info("Create HTML ok acctid:" + currentUser.AccountId + " FILE:" + createHtmlPath + htmlFileName);
            return createHtmlPath + htmlFileName;
        }

        private string CreateBillingPDF(string htmlPath)
        {
            // 从html路径中计算生成pdf的文件名
            int begin = htmlPath.IndexOf("DownloadFiles");
            int end = htmlPath.IndexOf(".html");
            string pdfFileName = htmlPath.Substring(begin + 14, end - begin - 14) + ".pdf";

            try
            {
                if (string.IsNullOrEmpty(htmlPath))
                    return null;
                string pdfPath = System.Web.HttpContext.Current.Server.MapPath("/BillingFiles/DownloadFiles/") + pdfFileName;
                Process p = new Process();
                string str = System.Web.HttpContext.Current.Server.MapPath("/BillingFiles/wkhtmltopdf-0.8.3.exe");
                if (!System.IO.File.Exists(str))
                    return null;
                p.StartInfo.FileName = str;
                p.StartInfo.Arguments = " \"" + htmlPath + "\" " + pdfPath;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.CreateNoWindow = true;
                p.Start();
                // 判断文件是否已经生成并且pdf写入完毕
                bool b = true;
                while (b)
                {
                    if (System.IO.File.Exists(pdfPath))
                    {

                        if (IsFileOpen(pdfPath))
                        {
                            System.Threading.Thread.Sleep(500);
                        }
                        else
                        {
                            b = false;
                        }
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(500);
                    }
                }
                string fileURL = String.Format("http://{0}{1}", Request.Url.Authority, Request.ApplicationPath) + "BillingFiles/DownloadFiles/" + pdfFileName;
                log.Info("Create PDF ok acctid:" + currentUser.AccountId + " FILE:" + fileURL + " " + pdfPath);
                return fileURL;
            }
            catch (Exception ex)
            {
                log.Error("CreatePDF Error: Acctid:" + currentUser.AccountId + ex.Message + ex.InnerException + ex.StackTrace);
            }
            return null;
        }


你可能感兴趣的:(C# 文件流下载相关整理)