Udostępnij przez


Pobieranie danych binarnych

Dotyczy: .NET Framework .NET Standard

Pobieranie ADO.NET

Domyślnie DataReader ładuje przychodzące dane jako wiersz, gdy tylko cały wiersz danych staje się dostępny. Duże obiekty binarne (BLOB) wymagają jednak innego traktowania, ponieważ mogą zawierać gigabajty danych, których nie można znaleźć w jednym wierszu. Metoda Command.ExecuteReader ma przeciążenie, które przyjmie argument CommandBehavior, aby zmodyfikować domyślne działanie DataReader. Możesz przekazać SequentialAccess do metody ExecuteReader , aby zmodyfikować domyślne zachowanie elementu DataReader , aby zamiast ładować wiersze danych, dane będą ładowane sekwencyjnie w miarę ich odbierania. Jest to idealne rozwiązanie do ładowania obiektów BLOB lub innych dużych struktur danych.

Uwaga / Notatka

Podczas ustawiania elementu DataReader do używania funkcji SequentialAccess należy zwrócić uwagę na sekwencję, w której uzyskujesz dostęp do zwracanych pól. Domyślne zachowanie elementu DataReader, które ładuje cały wiersz zaraz po udostępnieniu, umożliwia dostęp do pól zwracanych w dowolnej kolejności do momentu odczytania następnego wiersza. Jednak w przypadku korzystania z SequentialAccess należy uzyskać dostęp do pól zwracanych przez obiekt DataReader w kolejności. Jeśli na przykład zapytanie zwraca trzy kolumny, z których trzeci jest obiektem BLOB, przed uzyskaniem dostępu do danych obiektu BLOB w trzecim polu należy zwrócić wartości pierwszych i drugich pól. Jeśli uzyskujesz dostęp do trzeciego pola przed pierwszym lub drugim polem, wartości pierwszego i drugiego pola nie będą już dostępne. Dzieje się tak dlatego, że SequentialAccess zmodyfikowało DataReader tak, aby zwracał dane w sekwencji, a dane nie są dostępne po tym, jak DataReader je odczyta.

Podczas uzyskiwania dostępu do danych w polu OBIEKTU BLOB użyj metod dostępu typu GetBytes lub GetChars elementu DataReader, które wypełniają tablicę danymi. Można również użyć funkcji GetString dla danych znaków; Jednak aby oszczędzać zasoby systemowe, możesz nie chcieć załadować całej wartości obiektu BLOB do pojedynczej zmiennej ciągu. Zamiast tego można określić określony rozmiar buforu danych, który ma zostać zwrócony, oraz lokalizację początkową pierwszego bajtu lub znaku, który ma zostać odczytany z zwracanych danych. Funkcja GetBytes i GetChars zwróci wartość reprezentującą long liczbę zwracanych bajtów lub znaków. Jeśli przekażesz tablicę o wartości null do GetBytes lub GetChars, zwracana wartość długa będzie łączną liczbą bajtów lub znaków w obiekcie BLOB. Opcjonalnie możesz określić indeks w tablicy jako pozycję początkową dla odczytywanych danych.

Example

Poniższy przykład zwraca identyfikator wydawcy i logo z przykładowej bazy danych pubs. Identyfikator wydawcy (pub_id) jest polem znaków, a logo jest obrazem, który jest obiektem BLOB. Ponieważ pole logo jest mapą bitową, przykład zwraca dane binarne przy użyciu funkcji GetBytes. Zwróć uwagę, że identyfikator wydawcy jest dostępny dla bieżącego wiersza danych przed logo, ponieważ pola muszą być uzyskiwane sekwencyjnie.

// 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).  
System.IO.FileStream stream;
// Streams the BLOB to the FileStream object.  
System.IO.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 System.IO.FileStream(
        "logo" + pubID + ".bmp", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
    writer = new System.IO.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();

Zobacz także