Bagikan melalui


Mengambil Data Biner

Secara default, DataReader memuat data masuk sebagai baris segera setelah seluruh baris data tersedia. Objek besar biner (BLOB) memerlukan perawatan yang berbeda, namun, karena dapat berisi gigabyte data yang tidak dapat dimuat dalam satu baris. Metode Command.ExecuteReader memiliki kelebihan beban yang akan mengambil CommandBehavior argumen untuk mengubah perilaku default DataReader. Anda dapat meneruskan SequentialAccess ke ExecuteReader metode untuk memodifikasi perilaku DataReader default sehingga alih-alih memuat baris data, itu akan memuat data secara berurutan seperti yang diterima. Ini sangat ideal untuk memuat BLOB atau struktur data besar lainnya. Perhatikan bahwa perilaku ini mungkin bergantung pada sumber data Anda. Misalnya, mengembalikan BLOB dari Microsoft Access akan memuat seluruh BLOB yang dimuat ke dalam memori, daripada secara berurutan seperti yang diterima.

Saat mengatur DataReader untuk menggunakan SequentialAccess, penting untuk mencatat urutan di mana Anda mengakses bidang yang dikembalikan. Perilaku default DataReader, yang memuat seluruh baris segera setelah tersedia, memungkinkan Anda mengakses bidang yang dikembalikan dalam urutan apa pun hingga baris berikutnya dibaca. Namun, saat menggunakan SequentialAccess, Anda harus mengakses bidang yang dikembalikan oleh DataReader secara berurutan. Misalnya, jika kueri Anda mengembalikan tiga kolom, yang ketiga adalah BLOB, Anda harus mengembalikan nilai bidang pertama dan kedua sebelum mengakses data BLOB di bidang ketiga. Jika Anda mengakses bidang ketiga sebelum bidang pertama atau kedua, nilai bidang pertama dan kedua tidak lagi tersedia. Ini karena SequentialAccess telah memodifikasi DataReader untuk mengembalikan data secara berurutan dan data tidak tersedia setelah DataReader membacanya.

Saat mengakses data di bidang BLOB, gunakan aksesor berjenis GetBytes atau GetChars dari DataReader yang mengisi array dengan data. Namun, Anda juga dapat menggunakan GetString untuk data karakter; untuk menghemat sumber daya sistem, Anda mungkin tidak ingin memuat seluruh nilai BLOB ke dalam satu variabel string. Anda dapat menentukan ukuran buffer data tertentu yang akan dikembalikan, dan lokasi awal untuk byte atau karakter pertama yang akan dibaca dari data yang dikembalikan. GetBytes dan GetChars akan mengembalikan long nilai, yang menunjukkan jumlah byte atau karakter yang dikembalikan. Jika Anda meneruskan array null ke GetBytes atau GetChars, nilai panjang yang dikembalikan akan menjadi jumlah total byte atau karakter dalam BLOB. Anda dapat secara opsional menentukan indeks dalam array sebagai posisi awal untuk data yang sedang dibaca.

Contoh

Contoh berikut mengembalikan ID penerbit dan logo dari pubs database sampel di Microsoft SQL Server. ID penerbit (pub_id) adalah bidang karakter, dan logo adalah gambar yang berbentuk BLOB. logo Karena bidang adalah bitmap, contoh mengembalikan data biner menggunakan GetBytes. Perhatikan bahwa ID penerbit diakses untuk baris data saat ini sebelum logo, karena bidang harus diakses secara berurutan.

' Assumes that connection is a valid SqlConnection object.
Dim command As SqlCommand = New SqlCommand( _
  "SELECT pub_id, logo FROM pub_info", connection)

' Writes the BLOB to a file (*.bmp).
Dim stream As FileStream
' Streams the binary data to the FileStream object.
Dim writer As BinaryWriter
' The size of the BLOB buffer.
Dim bufferSize As Integer = 100
' 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

' The publisher id to use in the file name.
Dim pubID As String = ""

' Open the connection and read data into the DataReader.
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader(CommandBehavior.SequentialAccess)

Do While reader.Read()
  ' Get the publisher id, which must occur before getting the logo.
  pubID = reader.GetString(0)

  ' Create a file to hold the output.
  stream = New FileStream( _
    "logo" & pubID & ".bmp", FileMode.OpenOrCreate, FileAccess.Write)
  writer = New BinaryWriter(stream)

  ' 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
    writer.Write(outByte)
    writer.Flush()

    ' Reposition start index to end of the last buffer and fill buffer.
    startIndex += bufferSize
    retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)
  Loop

  ' Write the remaining buffer.
  writer.Write(outByte, 0 , retval - 1)
  writer.Flush()

  ' Close the output file.
  writer.Close()
  stream.Close()
Loop

' Close the reader and the connection.
reader.Close()
connection.Close()
// Assumes that connection is a valid SqlConnection object.
SqlCommand command = new SqlCommand(
  "SELECT pub_id, logo FROM pub_info", connection);

// Writes the BLOB to a file (*.bmp).
FileStream stream;
// Streams the BLOB to the FileStream object.
BinaryWriter writer;

// Size of the BLOB buffer.
int bufferSize = 100;
// The BLOB byte[] buffer to be filled by GetBytes.
byte[] outByte = new byte[bufferSize];
// The bytes returned from GetBytes.
long retval;
// The starting position in the BLOB output.
long startIndex = 0;

// The publisher id to use in the file name.
string pubID = "";

// Open the connection and read data into the DataReader.
connection.Open();
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

while (reader.Read())
{
  // Get the publisher id, which must occur before getting the logo.
  pubID = reader.GetString(0);

  // Create a file to hold the output.
  stream = new FileStream(
    "logo" + pubID + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);
  writer = new BinaryWriter(stream);

  // Reset the starting byte for the 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.
  while (retval == bufferSize)
  {
    writer.Write(outByte);
    writer.Flush();

    // Reposition start index to end of last buffer and fill buffer.
    startIndex += bufferSize;
    retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
  }

  // Write the remaining buffer.
  writer.Write(outByte, 0, (int)retval);
  writer.Flush();

  // Close the output file.
  writer.Close();
  stream.Close();
}

// Close the reader and the connection.
reader.Close();
connection.Close();

Lihat juga