чтение BLOB-изображения из базы данных MySQL
У меня возникли проблемы с чтением большого двоичного объекта из базы данных MySQL. Я получил его для успешной вставки в базу данных, но, похоже, не могу заставить его читать обратно. Я знаю, что некоторые из вас могут подумать, "почему он использует базу данных для хранения больших двоичных объектов для изображений, а не только пути к файлам / имена файлов", но я хочу иметь гибкость, и так как многие из этих изображений будут храниться на сервер, а не локально, это оптимизирует эффективность, а также позволяет мне при необходимости перемещать изображения на локальный. Я следовал (короткому) учебнику и написал следующий метод получения блоба;
public void getBlob(string query, string fileOut)
{
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, mConnection);
//the index number to write bytes to
long CurrentIndex = 0;
//the number of bytes to store in the array
int BufferSize = 100;
//The Number of bytes returned from GetBytes() method
long BytesReturned;
//A byte array to hold the buffer
byte[] Blob = new byte[BufferSize];
//We set the CommandBehavior to SequentialAccess
//so we can use the SqlDataReader.GerBytes() method.
MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (reader.Read())
{
FileStream fs = new FileStream(DeviceManager.picPath + "\\" + reader["siteBlobFileName"].ToString(), FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(fs);
CurrentIndex = 0;
BytesReturned = reader.GetBytes(1, CurrentIndex, Blob, 0,BufferSize);
while (BytesReturned == BufferSize)
{
writer.Write(Blob);
writer.Flush();
CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(1, CurrentIndex, Blob, 0, BufferSize);
}
writer.Write(Blob, 0, (int)BytesReturned);
writer.Flush();
writer.Close();
fs.Close();
}
reader.Close();
this.CloseConnection();
}
}
и я называю это так ...
mDBConnector.getBlob("SELECT siteMapPicture, siteBlobFilename FROM sites WHERE siteID = '" + DeviceManager.lastSite + "'", DeviceManager.picPath + "mappicsite" + DeviceManager.lastSite);
PBSite.BackgroundImage = Image.FromFile(DeviceManager.picPath + "mappicsite" + DeviceManager.lastSite);
Однако это происходит с ошибкой в BytesReturned = reader.GetBytes (1, CurrentIndex, Blob, 0, BufferSize); с ошибкой «GetBytes можно вызывать только для двоичных столбцов или столбцов guid». Я предполагаю, что это связано с моим типом поля в моей базе данных, но изменение столбца на тип двоичного означает, что мне нужно сохранить его как блоб, но я хочу оставить имя файла как обычную строку. Мне чего-то не хватает? или другой способ сделать это?
edit1: я думаю, что первый параметр для bytesreturned связан с колонкой в считывателе, установка этого значения в 0 дает ошибку «Недопустимая попытка прочитать предыдущий столбец с использованием SequentialAccess», плохо рассмотрим это.
edit2: удаление последовательного доступа дает мне файл размером 13 байт (который может быть только первой строкой, поэтому последовательный доступ читает все строки?), так что, возможно, я читаю столбцы в неправильном порядке.
редактировать 3: я считаю, что причина этой ошибки была из-за того, как я вводил в базу данных. изменив этот метод, мой saveBlob теперь выглядит так:
public void saveBlob(string filePath, string fileName, string siteID)
{
if (this.OpenConnection() == true)
{
//A stream of bytes that represnts the binary file
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
//The reader reads the binary data from the file stream
BinaryReader reader = new BinaryReader(fs);
//Bytes from the binary reader stored in BlobValue array
byte[] BlobValue = reader.ReadBytes((int)fs.Length);
fs.Close();
reader.Close();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = mConnection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO x (y, z) VALUES (@BlobFile, @BlobFileName)";
MySqlParameter BlobFileNameParam = new MySqlParameter("@BlobFileName", SqlDbType.NChar);
MySqlParameter BlobFileParam = new MySqlParameter("@BlobFile", SqlDbType.Binary);
cmd.Parameters.Add(BlobFileNameParam);
cmd.Parameters.Add(BlobFileParam);
BlobFileNameParam.Value = fileName;
BlobFileParam.Value = BlobValue;
cmd.ExecuteNonQuery();
this.CloseConnection();
}
}
Я пробежал через отладчик, и blobvalue и blobfileparam (@blobfile) имеют полный размер (около 150 КБ), но при выполнении запроса возникает ошибка, приводящая к следующей ошибке;
"unable to cast object of type 'system.byte[]' to type 'system.iconvertible"
Я изучил код и попытался изменить типы двоичных файлов на изображения, чтобы разрешить файлы большего размера, но выдает ту же ошибку. Кто-нибудь знает что-нибудь об этой новой информации?
редактировать 4: все исправлено. заметил, что в моем коде я использовал:
("@BlobFile", SqlDbType.Binary);
Поменял их на типы & quot; MySqlDbType & quot; (сумасшедший), и это позволило мне выбрать типы капель. Вещи наконец-то работают как задумано :)