J'ai une table nommée Blob (Id (int), Data (Image)). J'ai besoin d'utiliser SqlDataReader pour obtenir ces données d'image. Notez que je ne veux pas Response.Binarywrite () les données du navigateur. J'ai juste besoin de ces données binaires en octet [] pour les utiliser pour certaines opérations internes. La seule façon dont je peux penser est d'obtenir id en utilisant SqlDataReader et d'utiliser à nouveau SqlCommand.ExecuteScalar () pour obtenir cela comme octet [] pour un id donné. Puis-je utiliser uniquement le SqlDataReader (SqlCommand.ExecuteReader) pour obtenir ces données d'image sous forme d'octet []? Suis-je en train de manquer quelque chose?
Vous devriez pouvoir l'obtenir via: (byte[])reader["Data"]
.
Notez également que le type de données image
est obsolète et sera supprimé dans une future version de SQL Server; utilisez plutôt varbinary(max)
.
Oui, vous pouvez utiliser SqlDataReader.GetBytes
. Vous souhaiterez probablement passer null
pour le tampon lors du premier appel, pour connaître la quantité de données, puis l'appeler à nouveau avec un tampon de taille appropriée.
Vous pouvez simplement utiliser l'indexeur et transtyper le résultat dans un tableau d'octets - je ne suis pas sûr. Ça vaut le coup d'essayer :)
Dans .NET Framework 4.5, vous pouvez utiliser la méthode GetStream pour accéder aux données binaires en tant que Stream.
De MSDN . Je ne sais pas pourquoi je n'ai pas pu trouver ça avant.
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();
Utilisez cette fonction pour une lecture d'octets sûre et flexible:
/// <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;
}
Pas besoin d'utiliser le lecteur. Utilisez simplement un ensemble de données pour récupérer les valeurs de la base de données (en utilisant Proc stocké ou toute autre méthode) et tapez simplement le cast avec octet (code ci-dessous) et stockez-le dans un tableau d'octets. Votre travail est terminé.
byte[] productImage;
productImage = (byte[])ds.Tables[0].Rows[0]["Image"];