存储在varbinary(max)中的BCP查询输出图像

时间:2016-03-25 21:20:20

标签: c# sql-server image encoding bcp

我正在替换一个使用SqlDataReader从数据库中取出记录的.net应用。我将其替换为两部分进程,其中SQL Server将BCP queryout列中的数据varbinary(max)添加到平面文件,而.net应用程序将使用平面文件从每行创建.jpg图像byte[]列中的varbinary(max)

现有代码只是使用以下命令将列转换为字节数组:

(byte[])reader[field];

就我而言,我正在尝试使用:

System.Encoding.Default.GetBytes(stringFromFlatFile)

但无法在Windows计算机上查看生成的文件(错误已损坏/已损坏或过大)

我已经尝试过System.Encoding(Ascii,UTFX等)下的每一种编码类型而没有运气。

BCP queryout中是否需要执行额外步骤以保留varbinary(max)列中的字节数组?是否有任何特殊的SqlDataReader正在做什么来返回我需要添加到.net应用程序的字节数组?

1 个答案:

答案 0 :(得分:1)

我发布此更多信息作为参考,可能会引导您在特定情况下找到解决方案。

这对我来说已经24x7x365 8年了。

我想指出从不使用字符串转换或编码。字节始终保持为字节。

这是VB.Net代码

' The following code has run untouched for 6 years and gets images for me from the DB
' You may be able to see a detail that is relavent to you 
' NOTE The field binary read is by numeric field number - not by field name string
'      Notice the the buffer is grabbed in chunks into the buffer - not all at once 
'      Notice the CommandBehavior.SequentialAccess modifier
'
' There is no "conversion" of bytes thorugh any casting going on with encoding
' The bytes are left untouched 
'
' At the end is the snippit I use to write out the file to disk


Dim filledByteArray As Byte()
    filledByteArray = Nothing

Dim cn As New SqlConnection
Dim cmd As New SqlCommand 
Dim drNewPdf As SqlDataReader

            cn.ConnectionString = "MyConnectionStringHere"

            cmd.Connection = cn
            cmd.CommandText = "myStoredProcWithOneOftheFieldsIsBinary"
            cmd.CommandType = CommandType.StoredProcedure

            ' notice the command behavior argument
            cn.Open()
            drNewPdf = cmd.ExecuteReader(CommandBehavior.SequentialAccess)

            If drNewPdf.HasRows Then

                While drNewPdf.Read

            imgIdInt = drNewPdf.Item("FldNameOfInternalIntegerIdField")

                    ' - - - - - - - - - - - -  - - - - - -  -
                    ' Read the Binary Field Here
                    ' - - - - - - - - - - - -  - - - - - -  -


                    Dim ms As MemoryStream                 ' Writes the BLOB to a file (*.bmp).
                    Dim bw As BinaryWriter               ' Streams the binary data to the FileStream object.

                    Dim bufferSize As Integer = 100      ' The size of the BLOB buffer.
                    Dim outbyte(bufferSize - 1) As Byte  ' The BLOB byte() buffer to be filled by GetBytes.
                    Dim retval As Long                   ' The bytes returned from GetBytes.
                    Dim startIndex As Long = 0           ' The starting position in the BLOB output.



                    ' Create a stream to hold the output.
                    ms = New MemoryStream()
                    bw = New BinaryWriter(ms)

                    ' Reset the starting byte for a new BLOB.
                    startIndex = 0

                    ' READ THE FIELD HERE !!!! And Below in the loop
                    '5  '"ImageFieldBLOB"

                    ' Read bytes into outbyte() and retain the number of bytes returned.
                    retval = drNewPdf.GetBytes(5, startIndex, outbyte, 0, bufferSize)

                    ' Continue reading and writing while there are bytes beyond the size of the buffer.
                    Do While retval = bufferSize
                        bw.Write(outbyte)
                        bw.Flush()

                        ' Reposition the start index to the end of the last buffer and fill the buffer.
                        startIndex += bufferSize

                        ' READ THE FIELD HERE !!!!  And Above in the loop
                        '5 is the field index into the recordset - use field id 5 in this case 
                        ' Read bytes into outbyte() and retain the number of bytes returned.
                        retval = drNewPdf.GetBytes(5, startIndex, outbyte, 0, bufferSize)
                    Loop

                    ' Write the remaining buffer.
                    bw.Write(outbyte, System.Convert.ToInt32(0L), System.Convert.ToInt32(retval))
                    bw.Flush()


                    streamLEN = System.Convert.ToInt32(ms.Length)

                    filledByteArray = New Byte(streamLEN - 1) {}
                    ms.Seek(0, SeekOrigin.Begin)
                    ms.Read(filledByteArray, 0, streamLEN)


                    ' Close the output file.
                    bw.Close()
                    ms.Close()


                    ' - - - - - - - - - - - -  - - - - - -  -
                    ' End the Binary Field Read - Loop to next record -
                    ' - - - - - - - - - - - -  - - - - - -  -
                End While
            Else
                'No Rows ?

            End If


            cn.Close()
            cn.Dispose()





 ' A COMPLETELY DIFFERENT CHUNK OF CODE FOR PHYSICALLY WRITING TO DISK
            Dim outFileStream As FileStream

            outFileStream = New FileStream(selectedFileInfo.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite)

            outFileStream.Write(byteArrayFromDb, 0, byteArrayFromDb.Length)

            outFileStream.Flush()

            outFileStream.Close()

我的主要观点是永远不会有字符串转换为字节。