我們在軟體開發中,有相當多的時間花費在如何在UI中顯示一些圖片。通常,開發人員把圖片儲存到某個圖片檔案夾內,然後按要求顯示它們。做這項工作,我們需要把圖片路徑儲存到資料庫中,而真正的圖片檔案儲存體到某個檔案夾內。這樣我們可以有效減少資料庫的大小,但是這樣做將導致大量的磁碟空間被圖片檔案佔用,也使得這些圖片可以被輕易的訪問到。
讓我們來看一個解決方案。在接下來要介紹的代碼中我們將知道如何把一個圖片檔案直接的儲存到資料庫中,而不是放到磁碟上的某個檔案夾裡。有一些解決方案使用的是.net和sqlserver資料庫,這樣就可以使用預存程序了。
摘要
從這段代碼中我們將知道如何把一個圖片格式的檔案儲存體到資料庫中而不是儲存在某檔案夾的實體路徑中。
開發環境為在vs2005(website)中測試的;資料庫用的是sqlserver
vs2005(c#,website)+sqlserver
//儲存到資料庫
protected void btnSave_Click(object sender, EventArgs e)
{
// 上傳的圖片檔案到Image
System.Drawing.Image img = System.Drawing.Image.FromFile(fileImg.PostedFile.FileName);
// 以Jpeg格式存到記憶體中
System.IO.MemoryStream ms = new System.IO.MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
using (SqlConnection con = new SqlConnection("server=.;database=test;uid=sa;"))
{
SqlCommand cmd = new SqlCommand("spInsertImage", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ImageBinary", System.Data.SqlDbType.Image);
// 圖片的位元據
cmd.Parameters["@ImageBinary"].Value = ms.ToArray();
con.Open();
try
{
// 調預存程序
cmd.ExecuteNonQuery();
Response.Write("ok");
}
catch
{
Response.Write("error");
}
}
img.Dispose();
ms.Dispose();
ms.Flush();
}
分析
上面這段代碼實際上是將圖片檔案插入到資料庫中,接下來我將對這段代碼做一些說明。
你能看到變數“sInsertQuery”的初始值是“insert into images([image]) VALUES(?).”,
這是因為我們不能知道完整的查詢語句。我們需要增加一個二進位參數,這個參數的值為圖片檔案轉換成二進位後的值。
(很明顯,這個變數裡不能增加這個參數)
因為這個原因,我們使用了一個預留位置[?],它將被後來的參數“QueryParameter”代替。
因為需要建立一個二進位的OldDB參數,所以我們使用了FSO來建立。
當成功的建立了這個參數後,佔為符[?]將被這個參數所代替並執行。
//讀取
public void InitData()
{
// 資料庫中圖片的ID綁定到一個DropDownList
using (SqlConnection con = new SqlConnection("server=.;database=test;uid=sa;"))
{
SqlDataAdapter sda = new SqlDataAdapter("spSelectImage", con);
DataSet ds = new DataSet();
sda.Fill(ds);
ddlImage.DataSource = ds;
ddlImage.DataTextField = "ImageID";
ddlImage.DataValueField = "ImageID";
ddlImage.DataBind();
ddlImage.Items.Insert(0, new ListItem("清選擇", "0"));
sda.Dispose();
}
}
protected void ddlImage_SelectedIndexChanged(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection("server=.;database=test;uid=sa;"))
{
SqlCommand cmd = new SqlCommand("spSelectImageById", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ImageID", SqlDbType.Int);
// 在DropDownList中所選的ImageId
cmd.Parameters["@ImageID"].Value = Int32.Parse(ddlImage.SelectedValue);
con.Open();
SqlDataReader sdr = cmd.ExecuteReader();
Response.ClearContent();
Response.ContentType = "image/jpeg";
while (sdr.Read())
{
// 讀出相應記錄的二進位並送顯
Response.BinaryWrite((byte[])sdr[1]);
}
sdr.Close();
sdr.Dispose();
}
}
以上代碼實際上是從資料庫中讀取位元據,並在UI的picture box中顯示成圖片。接下來我們討論一下上面的幾行代碼。
首先要匯入System.IO命名空間以使用MemoryStream。
這裡的“Connection()”是一個使用者定義的類,它包含一個公用函數“doDBconnection()”。
這個公用函數拿到參數和資料庫名字之後便執行並返回結果。