時我們需要把一些大的數(shù)據(jù)對象如圖片、可執(zhí)行文件、視頻和文檔等數(shù)據(jù)存入數(shù)據(jù)庫。在ms sql server中,這要用到image數(shù)據(jù)類型,可以保存多達(dá)2g的數(shù)據(jù)。以下給出一個通過ado.net和ms sql server實現(xiàn)的小小的例子。
先創(chuàng)建一個測試數(shù)據(jù)表。
在查詢分析器中輸入并執(zhí)行以下語句:
create table [imgtable](
[imgid] [int] identity(1,1) not null,
[imgname] [varchar](100) collate chinese_prc_ci_as null,
[imgdata] [image] null,
primary key clustered
(
[imgid]
) on [primary]
) on [primary] textimage_on [primary]
這要在你所選的數(shù)據(jù)庫中就多了一個名叫imgtable的表。
vs中的代碼如下:
using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
using system.data.sqlclient;
using system.io;
namespace ado_demo
{
/// <summary>
/// form1 的摘要說明。
/// </summary>
public class ado_demo : system.windows.forms.form
{
private system.windows.forms.button button1;
private system.windows.forms.button button2;
private system.windows.forms.picturebox picturebox1;
private system.windows.forms.openfiledialog openfiledialog1;
private system.windows.forms.button button3;
/// <summary>
/// 必需的設(shè)計器變量。
/// </summary>
private system.componentmodel.container components = null;
public ado_demo()
{
//
// windows 窗體設(shè)計器支持所必需的
//
initializecomponent();
//
// todo: 在 initializecomponent 調(diào)用后添加任何構(gòu)造函數(shù)代碼
//
}
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
protected override void dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.dispose();
}
}
base.dispose( disposing );
}
#region windows 窗體設(shè)計器生成的代碼
/// <summary>
/// 設(shè)計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內(nèi)容。
/// </summary>
private void initializecomponent()
{
this.button1 = new system.windows.forms.button();
this.button2 = new system.windows.forms.button();
this.picturebox1 = new system.windows.forms.picturebox();
this.openfiledialog1 = new system.windows.forms.openfiledialog();
this.button3 = new system.windows.forms.button();
this.suspendlayout();
//
// button1
//
this.button1.location = new system.drawing.point(368, 48);
this.button1.name = "button1";
this.button1.size = new system.drawing.size(104, 23);
this.button1.tabindex = 0;
this.button1.text = "保存圖片";
this.button1.click += new system.eventhandler(this.button1_click);
//
// button2
//
this.button2.location = new system.drawing.point(368, 120);
this.button2.name = "button2";
this.button2.size = new system.drawing.size(104, 23);
this.button2.tabindex = 1;
this.button2.text = "顯示圖片";
this.button2.click += new system.eventhandler(this.button2_click);
//
// picturebox1
//
this.picturebox1.location = new system.drawing.point(8, 16);
this.picturebox1.name = "picturebox1";
this.picturebox1.size = new system.drawing.size(312, 288);
this.picturebox1.tabindex = 2;
this.picturebox1.tabstop = false;
//
// openfiledialog1
//
this.openfiledialog1.fileok += new system.componentmodel.canceleventhandler(this.openfiledialog1_fileok);
//
// button3
//
this.button3.location = new system.drawing.point(368, 200);
this.button3.name = "button3";
this.button3.size = new system.drawing.size(104, 23);
this.button3.tabindex = 1;
this.button3.text = "讀取文件并打開";
this.button3.click += new system.eventhandler(this.button3_click);
//
// ado_demo
//
this.autoscalebasesize = new system.drawing.size(6, 14);
this.clientsize = new system.drawing.size(496, 317);
this.controls.add(this.picturebox1);
this.controls.add(this.button2);
this.controls.add(this.button1);
this.controls.add(this.button3);
this.name = "ado_demo";
this.text = "ado_demo";
this.resumelayout(false);
}
#endregion
/// <summary>
/// 應(yīng)用程序的主入口點。
/// </summary>
[stathread]
static void main()
{
application.run(new ado_demo());
}
/// <summary>
/// 點擊打開文件對話框確定按鈕,將文件保存到數(shù)據(jù)庫中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void openfiledialog1_fileok(object sender, system.componentmodel.canceleventargs e)
{
string filename = this.openfiledialog1.filename;
sqlconnection conn = new sqlconnection("server=192.168.2.200;integrated security = sspi;database = northwind");
sqlcommand cmd = new sqlcommand("insert imgtable values(@imgname,@imgdata)",conn);
sqlparameter pm = new sqlparameter("@imgname",sqldbtype.varchar,100);
pm.value = filename;
sqlparameter pm1 = new sqlparameter("@imgdata",sqldbtype.image);
filestream fs = new filestream(filename,filemode.open);
int len = (int)fs.length;
byte[] filedata = new byte[len];
fs.read(filedata,0,len);
fs.close();
pm1.value = filedata;
cmd.parameters.add(pm);
cmd.parameters.add(pm1);
conn.open();
try
{
cmd.executenonquery();
}
catch(exception ex)
{
messagebox.show(ex.message);
}
}
private void button1_click(object sender, system.eventargs e)
{
this.openfiledialog1.showdialog();
}
/// <summary>
/// 從數(shù)據(jù)庫中讀取bitmap圖片并顯示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_click(object sender, system.eventargs e)
{
sqlconnection conn = new sqlconnection("server=192.168.2.200;integrated security = sspi;database = northwind");
sqlcommand cmd = new sqlcommand("select * from imgtable where imgname like '%bmp%'",conn);
conn.open();
sqldatareader dr;
try
{
dr = cmd.executereader();
dr.read();
system.data.sqltypes.sqlbinary sb = dr.getsqlbinary(2);
//或byte[] imagedata = (byte[])dr[2];
memorystream ms = new memorystream(sb.value);//在內(nèi)存中操作圖片數(shù)據(jù)
bitmap bmp = new bitmap(bitmap.fromstream(ms));
this.picturebox1.image = bmp;
dr.close();
}
catch(exception ex)
{
messagebox.show(ex.message);
}
finally
{
conn.close();
}
}
/// <summary>
/// 讀取文件并保存到硬盤,然后打開文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_click(object sender, system.eventargs e)
{
sqlconnection conn = new sqlconnection("server=192.168.2.200;integrated security = sspi;database = northwind");
sqlcommand cmd = new sqlcommand("select * from imgtable where imgname like '%doc'",conn);
conn.open();
sqldatareader dr;
try
{
dr = cmd.executereader();
dr.read();
system.data.sqltypes.sqlbinary sb = dr.getsqlbinary(2);
//或byte[] imagedata = (byte[])dr[2];
//filestream fs = new filestream(@"c:/temp.bmp",filemode.create);
string filename = @"c:/" + system.io.path.getfilename(dr.getstring(1));
filestream fs = new filestream(filename,filemode.create);
fs.write(sb.value,0,sb.value.length);
fs.close();
//this.picturebox1.image = image.fromfile(@"c:/temp.bmp");
system.diagnostics.process.start(filename);
dr.close();
}
catch(exception ex)
{
messagebox.show(ex.message);
}
finally
{
conn.close();
}
}
}
}
直接把整個文件讀取到內(nèi)存中的數(shù)組里對于小文件來說是沒問題的,但如果是大文件,特別是大小都超過了物理內(nèi)存的文件,可能會導(dǎo)致嚴(yán)重的內(nèi)存問題,需要分段讀取,并分段寫到數(shù)據(jù)庫。
新聞熱點
疑難解答
圖片精選