Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从数据库C打开二进制文件#_C#_Asp.net_Sql Server_Database_Pdf - Fatal编程技术网

C# 从数据库C打开二进制文件#

C# 从数据库C打开二进制文件#,c#,asp.net,sql-server,database,pdf,C#,Asp.net,Sql Server,Database,Pdf,我在SQL Server数据库中的列类型image中有PDF文件数据(以前的数据库设计器不好)。我需要做的是将二进制数据读取到客户端,这样他们就可以直接将PDF下载到他们的计算机上 到目前为止,我的代码如下: SqlConnection con = new SqlConnection(); con.ConnectionString = "casIntranetConnectionString"; SqlCommand com = new SqlCommand("SELECT [File], [

我在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");
}
我假设我需要读卡器来读取字节,但这就是我真正不知道我在做什么的地方。有什么建议吗


谢谢

我认为这应该是可行的:

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

您可以使用HttpResponse:

作为一个旁白,请考虑分离职责,您有一个负责访问数据库并写入响应的方法。这将导致将来的维护问题。请参见描述坚实的原则。如果您的代码片段是人为设计的,我深表歉意,但如果其他人偶然发现这个问题,我想我会包括一个“但不要这样做”的免责声明

如果您希望避免(尤其是服务器端代码),从而避免分配大字节数组,您可以执行流式处理,如下所示:

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

如果您经常提供同一个文件,那么最好将该文件直接写入服务器上的某个缓存目录,然后在后续请求中重新使用它,使用性能最好的API(如果可能,使用内核模式)。

在执行任何操作之前,您在2012年使用ADO.NET手动执行此操作有什么原因吗?@TimothyP是否愿意建议一个合适的替代方案?我建议您看看实体框架之类的技术,虽然我肯定无法告诉您它是否适合您的项目,但我认为“可能”是这样的。它让你专注于做什么,而不是怎么做。请不要冒犯,非故意的。您能直接将二进制文件插入媒体播放器中,这样就不需要下载,只需即时播放文件吗?
        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");                        
                    }
                }
            }
        }