时我们需要把一些大的数据对象如图片、可执行文件、视频和文档等数据存入数据库。在ms sql server中,这要用到image数据类型,可以保存多达2g的数据。以下给出一个通过ado.net和ms sql server实现的小小的例子。
先创建一个测试数据表。
在查询分析器中输入并执行以下语句:
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]
这要在你所选的数据库中就多了一个名叫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>
/// 必需的设计器变量。
/// </summary>
private system.componentmodel.container components = null;
public ado_demo()
{
//
// windows 窗体设计器支持所必需的
//
initializecomponent();
//
// todo: 在 initializecomponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.dispose();
}
}
base.dispose( disposing );
}
#region windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </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>
/// 应用程序的主入口点。
/// </summary>
[stathread]
static void main()
{
application.run(new ado_demo());
}
/// <summary>
/// 点击打开文件对话框确定按钮,将文件保存到数据库中
/// </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>
/// 从数据库中读取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);//在内存中操作图片数据
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();
}
}
}
}
直接把整个文件读取到内存中的数组里对于小文件来说是没问题的,但如果是大文件,特别是大小都超过了物理内存的文件,可能会导致严重的内存问题,需要分段读取,并分段写到数据库。
新闻热点
疑难解答
图片精选