Подтвердить что ты не робот

Получение двоичных данных с помощью SqlDataReader

У меня есть таблица с именем Blob (Id (int), Data (Image)). Мне нужно использовать SqlDataReader для получения данных изображения. Обратите внимание, что я не хочу отвечать на Response.Binarywrite() данные в браузер. Мне просто нужны эти двоичные данные как byte [], чтобы использовать их для некоторых внутренних операций. Единственный способ, которым я могу думать, - получить идентификатор, используя SqlDataReader, и снова использовать SqlCommand.ExecuteScalar(), чтобы получить это как byte [] для данного идентификатора. Могу ли я использовать только SqlDataReader (SqlCommand.ExecuteReader), чтобы получить данные этого изображения в виде байта []? Я что-то пропустил?

4b9b3361

Ответ 1

Вы должны быть в состоянии получить его через: (byte[])reader["Data"].

Также обратите внимание, что тип данных image устарел и будет удален в будущей версии SQL Server; используйте вместо этого varbinary(max).

Ответ 2

Да, вы можете использовать SqlDataReader.GetBytes. Вероятно, вы захотите передать null для буфера в первом вызове, чтобы узнать, сколько данных есть, а затем снова вызвать его с буфером соответствующего размера.

Вы можете просто использовать индексатор и передать результат в массив байтов - я не уверен. Стоит попробовать:)

Ответ 3

В .NET Framework 4.5 вы можете использовать метод GetStream для доступа к двоичным данным как к потоку.

Ответ 4

От MSDN. Не знаю, почему я не мог найти это раньше.

    SqlConnection pubsConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;");
    SqlCommand logoCMD = new SqlCommand("SELECT pub_id, logo FROM pub_info", pubsConn);

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

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

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

    // Open the connection and read data into the DataReader.
    pubsConn.Open();
    SqlDataReader myReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess);

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

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

      // Reset the starting byte for the new BLOB.
      startIndex = 0;

      // Read the bytes into outbyte[] and retain the number of bytes returned.
      retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);

      // Continue reading and writing while there are bytes beyond the size of the buffer.
      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;
        retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
      }

      // Write the remaining buffer.
      if(retval > 0) // if file size can divide to buffer size
          bw.Write(outbyte, 0, (int)retval); //original MSDN source had retval-1, a bug
      bw.Flush();

      // Close the output file.
      bw.Close();
      fs.Close();
    }

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

Ответ 5

Используйте эту функцию для безопасного и гибкого чтения байтов:

    /// <summary>
    /// Reads all available bytes from reader
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    private byte[] GetBytes(SqliteDataReader reader, int ordinal)
    {
        byte[] result = null;

        if (!reader.IsDBNull(ordinal))
        {
            long size = reader.GetBytes(ordinal, 0, null, 0, 0); //get the length of data 
            result = new byte[size];
            int bufferSize = 1024;
            long bytesRead = 0;
            int curPos = 0;
            while (bytesRead < size)
            {
                bytesRead += reader.GetBytes(ordinal, curPos, result, curPos, bufferSize);
                curPos += bufferSize;
            }
        }

        return result;
    }

Ответ 6

Не нужно использовать читателя. Просто используйте набор данных для извлечения значений из базы данных (с использованием сохраненного Proc или любого другого метода) и просто введите cast by by byte (код ниже) и сохраните его в массиве байтов. Ваша работа выполнена.

byte[] productImage;
productImage = (byte[])ds.Tables[0].Rows[0]["Image"];