Streaming data from SQL-Server to StreamObject

gfunk1016

New Member
Hey There,<BR><BR>Can anyone tell me how to get binary data stored in an SQL-Server into a Stream object in ASP.net<BR><BR>I have created a system that allows the user to upload any kind of file to<BR>the database. The file's binary data is stored in a BLOB field in the<BR>SQL-Server. I can output these data to a browser showing the image (if<BR>gif/jpg) or opening the acociated program (msword, acrobat).<BR><BR>Since I need to do a bit of image editing (on valid images) using the<BR>graphics class, I would like to get the filedata out as a physical file, but<BR>this gives me troubles. I have tried to use different combinations of<BR>streamobjects, but cannot figure out how to get the data from the<BR>sqlDataReader object to the Stream object.<BR><BR>Please help.<BR>Short answer: use the <BR>command.ExecuteReader(CommandBehavior.SequentialAc cess);<BR><BR>Long answer (docs):<BR>An important thing to note about setting the DataReader to use<BR>SequentialAccess is the sequence in which you access the fields returned.<BR>The default behavior of the DataReader, which loads an entire row as soon as<BR>it is available, allows you to access the fields returned in any order until<BR>the next row is read. When using SequentialAccess, you must access the<BR>different fields returned by the DataReader in order. That is, if your query<BR>returns three columns, the third of which is a BLOB, you must return the<BR>values of the first, then second fields returned before accessing the BLOB<BR>data. This is because the data is now returned in sequence and will not be<BR>available once the DataReader has read past it.<BR><BR>When accessing the data in the BLOB field, use the GetBytes typed accessor<BR>of the DataReader, which fills a byte array with the binary data. You can<BR>specify a specific buffer size of data to be returned, and a starting<BR>location for the first byte read from the returned data. GetBytes will<BR>return a long value, which represents the number of bytes returned. If you<BR>pass a null byte array to GetBytes, the long value returned will be the<BR>total number of bytes in the BLOB. You can optionally specify an index in<BR>the byte array as a start position for the data being read.<BR><BR>The following example returns the publisher id and logo from the pubs sample<BR>database in Microsoft SQL Server. The publisher id (pub_id) is a character<BR>field, and the logo is an image, which is a BLOB. Notice that the publisher<BR>id is accessed for the current row of data before the logo, as the fields<BR>must be accessed sequentially.<BR><BR>SqlConnection pubsConn = new SqlConnection("Data Source=localhost;Integrated<BR>Security=SSPI;Initial Catalog=pubs;");<BR>SqlCommand logoCMD = new SqlCommand("SELECT pub_id, logo FROM pub_info",<BR>pubsConn);<BR><BR>FileStream fs; // Writes BLOB to a file (*.bmp).<BR>BinaryWriter bw; // Streams BLOB to FileStream<BR>object.<BR><BR>int bufferSize = 100; // Size of BLOB buffer.<BR>byte[] outbyte = new byte[bufferSize]; // BLOB byte[] buffer to be filled<BR>by GetBytes.<BR>long retval; // Bytes returned from GetBytes.<BR>long startIndex = 0; // Starting position in BLOB output.<BR><BR>string pub_id = ""; // Publisher id use in file name.<BR><BR>// Open connection and read data into DataReader.<BR>pubsConn.Open();<BR>SqlDataReader myReader =<BR>logoCMD.ExecuteReader(CommandBehavior.SequentialAc cess);<BR><BR>while (myReader.Read())<BR>{<BR> // Get publisher id. Must be before logo.<BR> pub_id = myReader.GetString(0);<BR><BR> // Create file to hold output.<BR> fs = new FileStream("logo" + pub_id + ".bmp", FileMode.OpenOrCreate,<BR>FileAccess.Write);<BR> bw = new BinaryWriter(fs);<BR><BR> // Reset starting byte for new BLOB.<BR> startIndex = 0;<BR><BR> // Read bytes into outbyte[] and retain number of bytes returned.<BR> retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);<BR><BR> // Continue reading and writing while there are bytes beyond the size of<BR>the buffer.<BR> while (retval == bufferSize)<BR> {<BR> bw.Write(outbyte);<BR> bw.Flush();<BR><BR> // Reposition start index to end of last buffer and fill buffer.<BR> startIndex+= bufferSize;<BR> retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);<BR> }<BR><BR> // Write remaining buffer.<BR> bw.Write(outbyte);<BR> bw.Flush();<BR><BR> // Close output file.<BR> bw.Close();<BR> fs.Close();<BR>}<BR><BR>// Close reader and connection.<BR>myReader.Close();<BR>pubsConn.Close();<BR><BR>As I'm better at coding VB than C# i tried to convert the example you gave to VB. It worked... sorta. I generates the files, but the files won't show correctly?!? The gif files have wierd filesizes, so something is wrong !<BR><BR>Here's the code i use (can you see whats wrong?):<BR><BR>Sub Create_File()<BR> Dim fs As FileStream<BR> Dim bw As BinaryWriter<BR> Dim buffersize As Int32 = 100<BR> Dim outbyte As Byte()<BR> ReDim outbyte(buffersize)<BR> Dim retval As Long<BR> Dim pubid As String<BR> Dim startindex As Long<BR><BR> Dim SQLconn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("adminSQLconn"))<BR> Dim logoCMD As New SqlCommand("SELECT ID, FileData FROM FileVersions", SQLconn)<BR>' FileData is an IMAGE datatype in the SQL-Server.<BR> SQLconn.Open()<BR> Dim dbread As SqlDataReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAc cess)<BR> While dbread.Read<BR><BR> pubid = dbread.GetInt32(0).ToString<BR> fs = New FileStream("c:inetpubwwwrootatdotnetadminlogo" + pubid + ".bmp", FileMode.OpenOrCreate, FileAccess.Write)<BR> bw = New BinaryWriter(fs)<BR> startindex = 0<BR> retval = dbread.GetBytes(1, startindex, outbyte, 0, buffersize)<BR><BR> While retval = buffersize<BR> bw.Write(outbyte)<BR> bw.Flush()<BR> startindex += buffersize<BR> retval = dbread.GetBytes(1, startindex, outbyte, 0, buffersize)<BR> End While<BR><BR> bw.Write(outbyte)<BR> bw.Flush()<BR><BR> bw.Close()<BR> fs.Close()<BR><BR> End While<BR><BR> dbread.Close()<BR> SQLconn.Close()<BR><BR> End Sub<BR>
 
Back
Top