我正在替换一个使用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应用程序的字节数组?
答案 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()
我的主要观点是永远不会有字符串转换为字节。