locked
Improve reading and displaying binary field from database RRS feed

  • Question

  • User1092566934 posted

    Hi, 

    I have realized that this routine is not too efficiently, there are another way to accomplish this task, besides changing the size variable?

                        using (var reader = command.ExecuteReader())
                        {
                            if (reader.Read())
                            {
                                context.Response.Clear();
                                context.Response.ContentType = reader.GetString(1);
    
                                var cd = new System.Net.Mime.ContentDisposition();
                                cd.FileName = reader.GetString(2);
                                cd.Inline = true;
                                context.Response.AddHeader("Content-Disposition", cd.ToString());
    
                                long bytesRead;
                                int size = 1024;
                                var buffer = new byte[size];
                                long dataIndex = 0;
                                while ((bytesRead = reader.GetBytes(0, dataIndex, buffer, 0, buffer.Length)) > 0)
                                {
                                    var actual = new byte[bytesRead];
                                    Buffer.BlockCopy(buffer, 0, actual, 0, (int)bytesRead);
                                    context.Response.OutputStream.Write(actual, 0, actual.Length);
                                    dataIndex += bytesRead;
                                }
                            }
                        }



    Thursday, October 24, 2013 5:08 AM

Answers

  • User1092566934 posted

    Thanks for your reply PatriceSc, I finally opted by this solution: 

    using (var reader = command.ExecuteReader())
    {
        if (reader.Read())
        {
            context.Response.Clear();
            context.Response.ContentType = reader.GetString(1);
    
            var cd = new System.Net.Mime.ContentDisposition();
            cd.FileName = reader.GetString(2);
            cd.Inline = true;
            context.Response.AddHeader("Content-Disposition", cd.ToString());
    
            long bytesRead;
            int size = reader.GetInt32(3); //DATALENGTH
            var buffer = new byte[size];
            long dataIndex = 0;
    
            bytesRead = reader.GetBytes(0, dataIndex, buffer, 0, buffer.Length);
            var actual = new byte[bytesRead];
            Buffer.BlockCopy(buffer, 0, actual, 0, (int)bytesRead);
            context.Response.OutputStream.Write(actual, 0, actual.Length);
        }
    }

    In my old code, the value of size variable was 1024, this means that the loop jumped from 1024 to 1024. Now the value of size variable is the amount of bytes of the file, by using the sql function DATALENGTH I know the size of the file, so I don't need the loop and I get access to the file instantly.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 28, 2013 3:56 AM

All replies

  • User753101303 posted

    Hi,

    Never tried but you could perhaps try http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getstream.aspx with http://msdn.microsoft.com/en-us/library/system.io.stream.copyto.aspx and see how it performs ?

    Edit : also I quite like in such cases to set some expectation. For example you could see how much time it takes for a static file of the same size so that you can see how it compares with the "ideal" case.

    Thursday, October 24, 2013 9:20 AM
  • User1092566934 posted

    Thanks for your reply PatriceSc, I finally opted by this solution: 

    using (var reader = command.ExecuteReader())
    {
        if (reader.Read())
        {
            context.Response.Clear();
            context.Response.ContentType = reader.GetString(1);
    
            var cd = new System.Net.Mime.ContentDisposition();
            cd.FileName = reader.GetString(2);
            cd.Inline = true;
            context.Response.AddHeader("Content-Disposition", cd.ToString());
    
            long bytesRead;
            int size = reader.GetInt32(3); //DATALENGTH
            var buffer = new byte[size];
            long dataIndex = 0;
    
            bytesRead = reader.GetBytes(0, dataIndex, buffer, 0, buffer.Length);
            var actual = new byte[bytesRead];
            Buffer.BlockCopy(buffer, 0, actual, 0, (int)bytesRead);
            context.Response.OutputStream.Write(actual, 0, actual.Length);
        }
    }

    In my old code, the value of size variable was 1024, this means that the loop jumped from 1024 to 1024. Now the value of size variable is the amount of bytes of the file, by using the sql function DATALENGTH I know the size of the file, so I don't need the loop and I get access to the file instantly.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 28, 2013 3:56 AM