2016-03-25 28 views
0

SqlDataReaderを使用してデータベースからレコードを取り出した.netアプリケーションを置き換えます。私はそれをvarbinary(max)列からフラットファイルへのSQLサーバーBCP queryoutの2つの部分のプロセスに置き換え、varbinary(max)列にあるbyte[]から各行の.jpgイメージを作成するフラットファイルを消費します。私の場合はvarbinary(max)に格納されたBCPクエリアウトイメージ

(byte[])reader[field]; 

私が使用しようとしています:

System.Encoding.Default.GetBytes(stringFromFlatFile) 

をしかし、結果のファイルは、Windows上で閲覧することができません

は、既存のコードは、単に使用してバイト配列に列をキャスト(エラーの破損/破損、または大きすぎる)

System.Encoding(Ascii、UTFXなど)の下で、すべてのエンコーディングタイプを試しました。

BCP queryoutvarbinary(max)列にバイト配列を保持する必要がありますか? .netアプリケーションに追加する必要のあるバイト配列を返すために特別なものがありますか?SqlDataReaderは何ですか?

+1

バイナリjpgをファイルに書き込むコードを見てください。それはあなたに手がかりを与えるかもしれません。 BCPクエリアウトは、バイトの文字列表現を作成します。したがって、数値65 96 71のバイトの代わりに "0x659671"という文字列があります。また、そのフィールドから読んでいる既存のコードがある場合は、それを見てください。 –

+0

私はデータがテーブルにどのように格納されているかにアクセスすることはできませんが、あなたが正しい軌道にいることに同意します。私はvarbinaryフィールドからbytearrayに画像を引っ張るためにデータリーダーを使用するテストメソッドを作成しました。私はバイト配列のメモリストリームをシステムに使用しました。その後、System.Drawing.Imageを使用してjpgとして保存しました。画像はウィンドウで見ることができます。その後、バイト配列から文字列を作成するために使用できるすべてのエンコーディングメソッドを使用しました。それらのどれも、bcpによって作成された文字列のようには見えません。 – Roger

+0

Bcpは "FFD8FFE000104A46494600010100000100010000FFDB00430 ...."のような文字列を作成します。 – Roger

答えて

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() 

です。

+0

ありがとうございます。でも、私はすでにC#で動作するものがあります。私の希望はプロセスをスピードアップするためにbcpを使うことでした。理想的なアプローチではないかもしれません。 – Roger

関連する問題