首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从MySQL数据库读取BLOB图像

问从MySQL数据库读取BLOB图像
EN

Stack Overflow用户
提问于 2012-07-17 23:48:46
回答 1查看 14.5K关注 0票数 6

我在从MySQL数据库读回blob时遇到了一些问题。我已经成功地将其插入到数据库中,但似乎无法将其读回。我知道你们中的一些人可能会想“为什么他要使用数据库来存储图像的blobs,而不仅仅是文件路径/文件名”,但我想要有灵活性,因为许多这样的图像将存储在服务器上,而不是本地,这优化了效率,并允许我在需要时将图像移动到本地。我遵循了一个(简短的)教程,并编写了以下接收blob的方法;

代码语言:javascript
复制
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();
        }
    }

我这样叫它..

代码语言:javascript
复制
 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只能在binary或guid列上调用“。我假设这与我在数据库中的字段类型有关,但是将列更改为类型binary意味着我必须将其存储为blob类型,但我希望将文件名保留为常规字符串。我是不是漏掉了什么?或者是另一种方式呢?

edit1 :我认为bytesreturned的第一个参数与阅读器中的列有关,将其设置为0会产生错误"Invalid attempt to read a prior column using bytesreturned“,我将对此进行研究。

edit2 :删除顺序访问会得到一个13字节大小的文件(这可能只是第一行,这就是为什么顺序访问会读取所有行?)所以也许我读错了列的顺序..

编辑3:我认为这个错误的原因是由于我在数据库中输入的方式。更改此方法后,我的saveBlob现在看起来如下所示:

代码语言:javascript
复制
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)都有完整的大小(大约150k ),但它在执行查询时出错,给出了以下错误;

代码语言:javascript
复制
"unable to cast object of type 'system.byte[]' to type 'system.iconvertible"

我已经查看了代码,并尝试将类型二进制更改为图像,以允许更大的文件,但给出了相同的错误。有人知道这条新信息吗?

编辑4:修复所有问题。注意到在我的代码中我使用了:

代码语言:javascript
复制
 ("@BlobFile", SqlDbType.Binary);

将这些更改为"MySqlDbType“(derp)类型,并允许我选择blob的类型。事情终于按预期运行了:)

EN

回答 1

Stack Overflow用户

发布于 2012-07-25 17:26:56

你有没有先试过简化?与其一次读取BLOB 100字节,不如尝试简化代码,使其只读取文件的所有字节。这样,您就可以很容易地排除数据层问题。

以下文档还建议您将文件大小存储为另一列:Handling BLOB Data With Connector/NET

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11526209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档