0

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

将 reportID 调暗为整数 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

4

1 回答 1

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()
于 2013-05-04T19:19:02.890 回答