2012-01-24 53 views
4

我有一个SQL Server数据库中的PDF文件数据,在列类型image(坏之前的数据库设计器)。我需要做的是将二进制数据读取到客户端,以便他们可以直接将PDF下载到他们的计算机。从数据库C打开二进制文件#

到目前为止,我的代码如下:

SqlConnection con = new SqlConnection(); 
con.ConnectionString = "casIntranetConnectionString"; 

SqlCommand com = new SqlCommand("SELECT [File], [FileName] FROM [com].[catalog1] WHERE [FileName] = @filename"); 
com.Connection = con; 
com.Parameters.AddWithValue("filename", Request.QueryString["filename"]); 

con.Open(); 

SqlDataReader reader = com.ExecuteReader(); 

if (reader.Read()) 
{ 
    Response.Clear(); 
    Response.AddHeader("Content-Type", "application/pdf"); 
    Response.AddHeader("Content-Disposition", "inline; filename=" + Request.QueryString["filename"] + ".pdf"); 
} 

我假设我要去需要读者读出字节,但是这就是我真的不知道我做什么。有什么建议么?

谢谢!

+3

在你做任何事之前,你在2012年用ADO.NET手工做这件事有什么原因吗? – TimothyP

+2

@TimothyP谨慎建议一个适当的选择? – TJHeuvel

+0

我建议你看一下像实体框架这样的技术,虽然我当然不能告诉你它是否适合你的项目,但我认为它可能是“可能的”。它可以让你专注于什么,而不是如何。请不要冒犯,非意图的 – TimothyP

回答

5

可以使用的HttpResponse BinaryWrite method

var bytes = reader.GetSqlBytes(index); 
Response.BinaryWrite(bytes.Value); 

顺便说一句,请考虑将责任,你必须负责接入的方法数据库并写入响应。这将导致未来的维护问题。请参阅描述SOLID原则的here for a useful blog post。道歉,如果你的代码片段是人为的,但万一其他人绊倒这个问题的数字我会包括一个“,但不要这样做”这样的免责声明!

1

我认为,这应该工作:

if(reader.Read()) 
{ 
    Byte[] pdfData = (byte[])reader.GetValue(0);; 
    Response.Buffer = true; 
    Response.ContentType = "application/PDF"; 
    Response.BinaryWrite(pdfData); 
} 
3

如果你想避免heap fragmentation(尤其是服务器端代码),从而避免分配巨大的字节数组,你可以做流媒体,这样的事情:

 using (SqlConnection cnx = new SqlConnection(@"your connection string")) 
     { 
      cnx.Open(); 
      using (SqlCommand cmd = cnx.CreateCommand()) 
      { 
       cmd.CommandText = "SELECT [File] FROM [com].[catalog1] WHERE [FileName] = @filename"; 
       cmd.Parameters.AddWithValue("filename", Request.QueryString["filename"]); 

       // sequential access is used for raw access 
       using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) 
       { 
        if (reader.Read()) 
        { 
         // must be lower than 85K (to avoid Large Object Heap fragmentation) 
         byte[] chunk = new byte[0x10000]; 
         long read; 
         long offset = 0; 
         do 
         { 
          read = reader.GetBytes(0, offset, chunk, 0, chunk.Length); 
          if (read > 0) 
          { 
           Response.OutputStream.Write(chunk, 0, (int)read); 
           offset += read; 
          } 
         } 
         while (read > 0); 
         Response.AddHeader("Content-Type", "application/pdf"); 
         Response.AddHeader("Content-Disposition", "inline; filename=" + Request.QueryString["filename"] + ".pdf");       
        } 
       } 
      } 
     } 

如果你所服务的同一文件通常情况下,最好将此文件直接写入服务器上的某个缓存目录,然后将其重新用于后续请求,而性能最佳的Response.TransmitFile API(如果可能,则使用内核模式)。