在块中写入BLOB数据的问题(8k)

时间:2013-03-16 17:29:52

标签: asp.net vb.net sqldatareader

我正在尝试将BLOB数据写入word文件。这是我的代码

Dim reportID As Integer            reportID = table1.report_output_data_id

       Dim aSqlStr As String = "SELECT file_data FROM table2 WHERE report_output_data_id = " + Convert.ToString(reportID )
       Dim reader As SqlDataReader = CType(WebSession.DataObjectFactory.GetDataProvider("EGDatabase"), cDataProviderSQL).PopulateDataReader(aSqlStr)

       ' The size of the BLOB buffer.
       Dim bufferSize As Integer = 8192
       ' The BLOB byte() buffer to be filled by GetBytes.
       Dim outByte(bufferSize - 1) As Byte
       ' The bytes returned from GetBytes.
       Dim retval As Long
       ' The starting position in the BLOB output.
       Dim startIndex As Long = 0
       Do While reader.Read()
           ' Reset the starting byte for a new BLOB.
           startIndex = 0
           ' Read bytes into outByte() and retain the number of bytes returned.
           retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize)

           ' Continue while there are bytes beyond the size of the buffer.
           Do While retval = bufferSize
               Response.BinaryWrite(outByte)

               ' Reposition start index to end of the last buffer and fill buffer.
               startIndex += bufferSize
               retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize)
           Loop
           Response.BinaryWrite(outByte)
       Loop
       reader.Close()

我一次写8k,因为当数据很大时我早先没有内存问题说1GB。如果我使用

,而不是上面的代码

Response.BinaryWrite(table2.file_data)

一切正常。

那么请告诉我使用sqldatareader的问题是什么?

我正在考虑的文件大小是31794字节

仅供参考:我正在使用CommandBehavior.SequentialAccess

1 个答案:

答案 0 :(得分:1)

在写入BLOB数据时,垃圾数据被添加到文件中。

例如,文件大小为33959字节

循环1将处理0 - 8192个字节(增量为8k) 环2 8192-16384 环3 16384 - 24576 循环4 24576 - 32768 循环5 32768 - 33959(实际文件大小)

retval = reader.GetBytes(0,startIndex,outByte,0,bufferSize)

在循环5中,我们只有1191个字节。因此在outbyte数组中,前1191个项目将被读取器在此时间点读取的字节替换为1191,但是outbyte数组中的剩余项目仍将保留垃圾值(从先前的循环中出现)作为outbyte数组大小为8k。

如果要写入的剩余数据小于8k,则使用新的outbyte数组而不是默认数组(8k)。这是代码更改。

Dim aSqlStr As String =“SELECT datalength(file_data),file_data FROM table2 WHERE report_output_data_id =”+ Convert.ToString(reportID)        Dim reader As SqlDataReader = CType(WebSession.DataObjectFactory.GetDataProvider(“EGDatabase”),cDataProviderSQL).PopulateDataReader(aSqlStr)

   ' The size of the BLOB buffer.
   Dim bufferSize As Integer = 8192
   ' The BLOB byte() buffer to be filled by GetBytes.
   Dim outByte(bufferSize - 1) As Byte
   ' The bytes returned from GetBytes.
   Dim retval As Long
   ' The starting position in the BLOB output.
   Dim startIndex As Long = 0
           Do While reader.Read()
               ' Get file size from BLOB buffer.
               fileSize = reader.GetInt32(0)
               If fileSize > bufferSize Then

                   ' Reset the starting byte for a new BLOB.
                   startIndex = 0
                   ' Read bytes into outByte() and retain the number of bytes returned.
                   retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)

                   ' Continue while there are bytes beyond the size of the buffer.
                   Do While retval = bufferSize
                       Response.BinaryWrite(outByte)
                       ' Reposition start index to end of the last buffer and fill buffer.
                       startIndex += bufferSize
                       Dim aRemainingBytes = fileSize - startIndex
                       If Not aRemainingBytes < bufferSize Then
                            retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)
                       Else
                            Dim outByteRemaining(aRemainingBytes - 1) As Byte
                            retval = reader.GetBytes(1, startIndex, outByteRemaining, 0, aRemainingBytes)
                            Response.BinaryWrite(outByteRemaining)
                       End If
                    Loop
                Else
                    Response.BinaryWrite(aReportOutput.GetRelatedPropertyValue("ReportOutputData.FileData"))
                End If
           Loop
           reader.Close()