0

Word ファイルに BLOB データを書き込もうとしています。これが私のコードです

薄暗い 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()

データが 1 GB と大きい場合、以前にメモリ不足の問題があったため、一度に 8k を書き込んでいます。上記のコードの代わりに、使用すると

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 未満の場合は、デフォルトの配列 (8k) の代わりに新しい outbyte 配列を使用しました。ここにコードの変更があります。

Dim aSqlStr As String = "SELECT datalength(file_data),file_data FROM table2 WHERE report_output_data_id = " + Convert.ToString(reportID ) Dim リーダー 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 に答える