有时我们需要把一些大的数据对象如图片、可执行文件、视频和文档等数据存入数据库。在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中的代码如下:
1
using
System;
2
using
System.Drawing;
3
using
System.Collections;
4
using
System.ComponentModel;
5
using
System.Windows.Forms;
6
using
System.Data;
7
using
System.Data.SqlClient;
8
using
System.IO;
9
10
namespace
ADO_Demo
11
{
12
/**//// <summary>
13
/// Form1 的摘要说明。
14
/// </summary>
15
public class ADO_Demo : System.Windows.Forms.Form
16
{
17
private System.Windows.Forms.Button button1;
18
private System.Windows.Forms.Button button2;
19
private System.Windows.Forms.PictureBox pictureBox1;
20
private System.Windows.Forms.OpenFileDialog openFileDialog1;
21
private System.Windows.Forms.Button button3;
22
/**//// <summary>
23
/// 必需的设计器变量。
24
/// </summary>
25
private System.ComponentModel.Container components = null;
26
27
public ADO_Demo()
28
{
29
//
30
// Windows 窗体设计器支持所必需的
31
//
32
InitializeComponent();
33
34
//
35
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
36
//
37
}
38
39
/**//// <summary>
40
/// 清理所有正在使用的资源。
41
/// </summary>
42
protected override void Dispose( bool disposing )
43
{
44
if( disposing )
45
{
46
if (components != null)
47
{
48
components.Dispose();
49
}
50
}
51
base.Dispose( disposing );
52
}
53
54
Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码
55
/**//// <summary>
56
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
57
/// 此方法的内容。
58
/// </summary>
59
private void InitializeComponent()
60
{
61
this.button1 = new System.Windows.Forms.Button();
62
this.button2 = new System.Windows.Forms.Button();
63
this.pictureBox1 = new System.Windows.Forms.PictureBox();
64
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
65
this.button3 = new System.Windows.Forms.Button();
66
this.SuspendLayout();
67
//
68
// button1
69
//
70
this.button1.Location = new System.Drawing.Point(368, 48);
71
this.button1.Name = "button1";
72
this.button1.Size = new System.Drawing.Size(104, 23);
73
this.button1.TabIndex = 0;
74
this.button1.Text = "保存图片";
75
this.button1.Click += new System.EventHandler(this.button1_Click);
76
//
77
// button2
78
//
79
this.button2.Location = new System.Drawing.Point(368, 120);
80
this.button2.Name = "button2";
81
this.button2.Size = new System.Drawing.Size(104, 23);
82
this.button2.TabIndex = 1;
83
this.button2.Text = "显示图片";
84
this.button2.Click += new System.EventHandler(this.button2_Click);
85
//
86
// pictureBox1
87
//
88
this.pictureBox1.Location = new System.Drawing.Point(8, 16);
89
this.pictureBox1.Name = "pictureBox1";
90
this.pictureBox1.Size = new System.Drawing.Size(312, 288);
91
this.pictureBox1.TabIndex = 2;
92
this.pictureBox1.TabStop = false;
93
//
94
// openFileDialog1
95
//
96
this.openFileDialog1.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog1_FileOk);
97
//
98
// button3
99
//
100
this.button3.Location = new System.Drawing.Point(368, 200);
101
this.button3.Name = "button3";
102
this.button3.Size = new System.Drawing.Size(104, 23);
103
this.button3.TabIndex = 1;
104
this.button3.Text = "读取文件并打开";
105
this.button3.Click += new System.EventHandler(this.button3_Click);
106
//
107
// ADO_Demo
108
//
109
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
110
this.ClientSize = new System.Drawing.Size(496, 317);
111
this.Controls.Add(this.pictureBox1);
112
this.Controls.Add(this.button2);
113
this.Controls.Add(this.button1);
114
this.Controls.Add(this.button3);
115
this.Name = "ADO_Demo";
116
this.Text = "ADO_Demo";
117
this.ResumeLayout(false);
118
119
}
120
#endregion
121
122
/**//// <summary>
123
/// 应用程序的主入口点。
124
/// </summary>
125
[STAThread]
126
static void Main()
127
{
128
Application.Run(new ADO_Demo());
129
}
130
131
/**//// <summary>
132
/// 点击打开文件对话框确定按钮,将文件保存到数据库中
133
/// </summary>
134
/// <param name="sender"></param>
135
/// <param name="e"></param>
136
private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
137
{
138
string filename = this.openFileDialog1.FileName;
139
SqlConnection conn = new SqlConnection("server=192.168.2.200;integrated security = sspi;database = northwind");
140
SqlCommand cmd = new SqlCommand("insert imgtable values(@imgname,@imgData)",conn);
141
SqlParameter pm = new SqlParameter("@imgname",SqlDbType.VarChar,100);
142
pm.Value = filename;
143
SqlParameter pm1 = new SqlParameter("@imgData",SqlDbType.Image);
144
FileStream fs = new FileStream(filename,FileMode.Open);
145
int len = (int)fs.Length;
146
byte[] fileData = new byte[len];
147
fs.Read(fileData,0,len);
148
fs.Close();
149
150
pm1.Value = fileData;
151
cmd.Parameters.Add(pm);
152
cmd.Parameters.Add(pm1);
153
154
conn.Open();
155
try
156
{
157
cmd.ExecuteNonQuery();
158
}
159
catch(Exception ex)
160
{
161
MessageBox.Show(ex.Message);
162
}
163
164
165
}
166
167
private void button1_Click(object sender, System.EventArgs e)
168
{
169
this.openFileDialog1.ShowDialog();
170
}
171
172
/**//// <summary>
173
/// 从数据库中读取bitmap图片并显示
174
/// </summary>
175
/// <param name="sender"></param>
176
/// <param name="e"></param>
177
private void button2_Click(object sender, System.EventArgs e)
178
{
179
SqlConnection conn = new SqlConnection("server=192.168.2.200;integrated security = sspi;database = northwind");
180
SqlCommand cmd = new SqlCommand("select * from imgtable where imgname like '%bmp%'",conn);
181
conn.Open();
182
SqlDataReader dr;
183
try
184
{
185
dr = cmd.ExecuteReader();
186
dr.Read();
187
System.Data.SqlTypes.SqlBinary sb = dr.GetSqlBinary(2);
188
//或byte[] imageData = (byte[])dr[2];
189
MemoryStream ms = new MemoryStream(sb.Value);//在内存中操作图片数据
190
Bitmap bmp = new Bitmap(Bitmap.FromStream(ms));
191
this.pictureBox1.Image = bmp;
192
dr.Close();
193
}
194
catch(Exception ex)
195
{
196
MessageBox.Show(ex.Message);
197
}
198
finally
199
{
200
conn.Close();
201
}
202
}
203
204
/**//// <summary>
205
/// 读取文件并保存到硬盘,然后打开文件
206
/// </summary>
207
/// <param name="sender"></param>
208
/// <param name="e"></param>
209
private void button3_Click(object sender, System.EventArgs e)
210
{
211
SqlConnection conn = new SqlConnection("server=192.168.2.200;integrated security = sspi;database = northwind");
212
SqlCommand cmd = new SqlCommand("select * from imgtable where imgname like '%doc'",conn);
213
conn.Open();
214
SqlDataReader dr;
215
try
216
{
217
dr = cmd.ExecuteReader();
218
dr.Read();
219
System.Data.SqlTypes.SqlBinary sb = dr.GetSqlBinary(2);
220
//或byte[] imageData = (byte[])dr[2];
221
//FileStream fs = new FileStream(@"C:/temp.bmp",FileMode.Create);
222
string filename = @"C:/" + System.IO.Path.GetFileName(dr.GetString(1));
223
FileStream fs = new FileStream(filename,FileMode.Create);
224
fs.Write(sb.Value,0,sb.Value.Length);
225
fs.Close();
226
//this.pictureBox1.Image = Image.FromFile(@"C:/temp.bmp");
227
System.Diagnostics.Process.Start(filename);
228
dr.Close();
229
}
230
catch(Exception ex)
231
{
232
MessageBox.Show(ex.Message);
233
}
234
finally
235
{
236
conn.Close();
237
}
238
}
239
}
240
}

2

3

4

5

6

7

8

9

10

11



12


13

14

15

16



17

18

19

20

21

22


23

24

25

26

27

28



29

30

31

32

33

34

35

36

37

38

39


40

41

42

43



44

45



46

47



48

49

50

51

52

53

54


55


56

57

58

59

60



61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122


123

124

125

126

127



128

129

130

131


132

133

134

135

136

137



138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156



157

158

159

160



161

162

163

164

165

166

167

168



169

170

171

172


173

174

175

176

177

178



179

180

181

182

183

184



185

186

187

188

189

190

191

192

193

194

195



196

197

198

199



200

201

202

203

204


205

206

207

208

209

210



211

212

213

214

215

216



217

218

219

220

221

222

223

224

225

226

227

228

229

230

231



232

233

234

235



236

237

238

239

240

直接把整个文件读取到内存中的数组里对于小文件来说是没问题的,但如果是大文件,特别是大小都超过了物理内存的文件,可能会导致严重的内存问题,需要分段读取,并分段写到数据库。