Sha*_*e.C 6 .net c# mysql blob
我在从MySQL数据库中读取blob时遇到了一些麻烦.我已经把它成功插入数据库,但似乎无法让它回读.我知道你们中的一些人可能在想"为什么他使用数据库存储图像的斑点,而不仅仅是文件路径/文件名",但我想要有灵活性,因为很多这些图像都会存储在服务器而不是本地服务器,这可以优化效率,并允许我根据需要将图像移动到本地.我已经按照(简短)教程编写了以下方法来接收blob;
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我这样称呼它..
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);
Run Code Online (Sandbox Code Playgroud)
然而,它在BytesReturned = reader.GetBytes(1,CurrentIndex,Blob,0,BufferSize)上出错; 错误"只能在二进制或guid列上调用GetBytes".我假设这与我的数据库中的字段类型有关,但是将列更改为类型二进制意味着我必须将其存储为blob类型,但我想将文件名保留为常规字符串.有什么我想念的吗?或另一种方式吗?
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经浏览了调试器,blobvalue和blobfileparam(@blobfile)都有完整的大小(大约150k),但执行查询时出错,给出以下错误;
"unable to cast object of type 'system.byte[]' to type 'system.iconvertible"
Run Code Online (Sandbox Code Playgroud)
我已经看了一下代码,并尝试将二进制类型更改为图像,以允许更大的文件,但给出相同的错误.有人对这些新信息有所了解吗?
编辑4:修复一切.注意到我在我的代码中使用:
("@BlobFile", SqlDbType.Binary);
Run Code Online (Sandbox Code Playgroud)
将这些更改为类型"MySqlDbType"(derp),它允许我选择blob的类型.事情终于按预期工作了:)
您是否尝试过先简化?不要一次读取 BLOB 100 个字节,而是尝试简化代码以仅将所有字节读取到文件中。这样您就可以轻松排除数据层问题。
以下文档还建议您将文件大小存储为另一列:Handling BLOB Data With Connector/NET
| 归档时间: |
|
| 查看次数: |
13628 次 |
| 最近记录: |