簡體   English   中英

從數據庫C#打開二進制文件

[英]Open Binary File From Database C#

我在SQL Server數據庫中的列類型image (壞的以前的數據庫設計器)中有PDF文件數據。 我需要做的是將二進制數據讀出到客戶端,以便他們可以將PDF直接下載到他們的計算機上。

到目前為止,我的代碼如下:

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");
}

我假設我需要讀者讀出字節,但這就是我不知道我在做什么的地方。 有什么建議么?

謝謝!

您可以使用HttpResponse BinaryWrite方法

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

順便說一句,請考慮分離職責,您有一個負責訪問數據庫和寫入響應的方法。 這將導致將來出現維護問題。 請參閱此處以獲取描述SOLID原則的有用博客文章 抱歉,如果你的代碼片段是人為的,但萬一其他人偶然發現這個問題,我想包括一個“但不要這樣做”的免責聲明!

如果你想避免堆碎片 (特別是服務器端代碼),從而避免分配巨大的字節數組,你可以做流式傳輸,如下所示:

        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");                        
                    }
                }
            }
        }

如果您經常提供相同的文件,那么最好將此文件直接寫入服務器上的某個Cache目錄,然后將其重新用於后續請求,使用Response.TransmitFile API,這是性能最佳的(使用)內核模式,如果可能)。

我認為這應該有效:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM