Delen via


Binaire gegevens ophalen

DataReader Standaard worden binnenkomende gegevens als een rij geladen zodra er een hele rij met gegevens beschikbaar is. Binaire grote objecten (BLOBs) hebben echter een andere behandeling nodig, omdat ze gigabytes aan gegevens kunnen bevatten die niet in één rij kunnen worden opgenomen. De methode Command.ExecuteReader heeft een overbelasting waarmee een CommandBehavior argument wordt gebruikt om het standaardgedrag van de DataReader te wijzigen. U kunt SequentialAccess aan de ExecuteReader-methode doorgeven om het standaardgedrag van de DataReader-methode te wijzigen, zodat het niet rijen met gegevens laadt, maar gegevens sequentieel laadt terwijl deze worden ontvangen. Dit is ideaal voor het laden van BLOBs of andere grote gegevensstructuren. Houd er rekening mee dat dit gedrag mogelijk afhankelijk is van uw gegevensbron. Als u bijvoorbeeld een BLOB van Microsoft Access retourneert, wordt de hele BLOB in het geheugen geladen, in plaats van sequentieel verwerkt te worden zoals deze binnenkomt.

Bij het instellen van DataReader om SequentialAccess te gebruiken, is het belangrijk om rekening te houden met de volgorde waarin u toegang krijgt tot de geretourneerde velden. Het standaardgedrag van de DataReader, waarmee een hele rij wordt geladen zodra deze beschikbaar is, stelt u in staat toegang te krijgen tot de velden in willekeurige volgorde totdat de volgende rij wordt gelezen. Wanneer u echter SequentialAccess gebruikt, moet u toegang krijgen tot de velden die door DataReader worden geretourneerd in de juiste volgorde. Als uw query bijvoorbeeld drie kolommen retourneert, waarvan de derde een BLOB is, moet u de waarden van de eerste en tweede velden retourneren voordat u de BLOB-gegevens in het derde veld opent. Als u het derde veld voor de eerste of tweede velden opent, zijn de eerste en tweede veldwaarden niet meer beschikbaar. Dit komt doordat SequentialAccess de DataReader heeft aangepast om gegevens in volgorde terug te geven, en de gegevens niet beschikbaar zijn nadat de DataReader er voorbij heeft gelezen.

Wanneer u de gegevens in het BLOB-veld opent, gebruikt u de GetBytes of GetChars getypte accessors van de DataReader, die een array vullen met gegevens. U kunt echter ook gebruiken GetString voor tekengegevens. als u systeembronnen wilt besparen, wilt u mogelijk geen volledige BLOB-waarde laden in één tekenreeksvariabele. U kunt in plaats daarvan een specifieke buffergrootte opgeven voor gegevens die moeten worden geretourneerd en een beginlocatie voor de eerste byte of het eerste teken dat moet worden gelezen uit de geretourneerde gegevens. GetBytes en GetChars retourneert een long waarde, die het aantal geretourneerde bytes of tekens aangeeft. Als u een null-matrix doorgeeft aan GetBytes of GetChars, is de geretourneerde lange waarde het totale aantal bytes of tekens in de BLOB. U kunt desgewenst een index in de matrix opgeven als uitgangspunt voor de gegevens die worden gelezen.

Voorbeeld

In het volgende voorbeeld worden de uitgevers-id en het logo van de pubs voorbeelddatabase in Microsoft SQL Server geretourneerd. De uitgevers-id (pub_id) is een tekenveld en het logo is een afbeelding, een BLOB. Omdat het logo veld een bitmap is, retourneert het voorbeeld binaire gegevens met behulp van GetBytes. U ziet dat de uitgever-id wordt geopend voor de huidige gegevensrij vóór het logo, omdat de velden opeenvolgend moeten worden geopend.

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

Zie ook