Načítání binárních dat

Ve výchozím nastavení dataReader načte příchozí data jako řádek, jakmile bude k dispozici celý řádek dat. Binární velké objekty (BLOB) však potřebují jinou léčbu, protože můžou obsahovat gigabajty dat, která nemohou být obsažena v jednom řádku. Command.ExecuteReader metoda má přetížení, které vezme CommandBehavior argument pro úpravu výchozí chování DataReader. Můžete předat SequentialAccessExecuteReader metoda upravit výchozí chování DataReader tak, aby místo načítání řádků dat, bude načítat data postupně při přijetí. To je ideální pro načítání objektů BLOB nebo jiných velkých datových struktur. Upozorňujeme, že toto chování může záviset na vašem zdroji dat. Například vrácení objektu BLOB z Microsoft Accessu načte celý objekt BLOB načtený do paměti, nikoli postupně při přijetí.

Při nastavování Čtečky dat pro použití sekvenčního přístupu je důležité poznamenat posloupnost, ve které přistupujete k vrácených polím. Výchozí chování třídy DataReader, které načte celý řádek, jakmile je k dispozici, umožňuje přístup k polím vráceným v libovolném pořadí, dokud nebude přečten další řádek. Při použití sekvenčního přístupu však musíte přistupovat k polím vráceným Čtečkou dat v pořadí. Pokud například dotaz vrátí tři sloupce, třetí z toho je objekt BLOB, musíte před přístupem k datům objektu blob ve třetím poli vrátit hodnoty prvních a druhých polí. Pokud přistupujete ke třetímu poli před prvním nebo druhým polem, hodnoty prvního a druhého pole už nebudou k dispozici. Je to proto, že Sekvenčníaccess upravil Čtečku dat tak, aby vracela data v sekvenci a data nejsou k dispozici po přečtení čtečky dat.

Při přístupu k datům v poli OBJEKT BLOB použijte přístupové objekty TypeD GetBytes nebo GetChars třídy DataReader, které vyplní pole daty. Pro data znaků ale můžete použít i GetString . chcete-li šetřit systémové prostředky, možná nebudete chtít načíst celou hodnotu objektu BLOB do jedné řetězcové proměnné. Místo toho můžete zadat konkrétní velikost vyrovnávací paměti dat, která se mají vrátit, a počáteční umístění prvního bajtu nebo znaku, který se má číst z vrácených dat. Funkce GetBytes a GetChars vrátí long hodnotu, která představuje počet vrácených bajtů nebo znaků. Pokud předáte pole null getBytes nebo GetChars, bude vrácená dlouhá hodnota celkový počet bajtů nebo znaků v objektu BLOB. Volitelně můžete v poli zadat index jako výchozí pozici pro čtení dat.

Příklad

Následující příklad vrátí ID a logo vydavatele z ukázkové databáze pubs v Microsoft SQL Serveru. ID vydavatele (pub_id) je pole znaku a logo je obrázek, což je objekt BLOB. Vzhledem k tomu, že pole s logem je rastrový obrázek, vrátí příklad binární data pomocí metody GetBytes. Všimněte si, že ID vydavatele je přístupné pro aktuální řádek dat před logem, protože pole musí být přístupná postupně.

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

Viz také