问题描述:将图片、二进制文件内容等数据存储在数据库中,并能从数据库中取出还原为图片或文件,数据库存储二进制数据用varbinary字段。
分析:由于之前数据库中没有用过varbinary存储数据,首先要把varbinary搞懂了,其次就是图片类型与二进制类型之间的转换,文件类型与二进制类型之间的转换。
准备工作:
1.varbinary 与 binary的区别:
固定长度 (binary) 的或可变长度 (varbinary) 的 binary 数据类型。
binary [ ( n ) ]
固定长度的 n 个字节二进制数据。N 必须从 1 到 8,000。存储空间大小为 n+4 字节。
varbinary [ ( n ) ]
n 个字节变长二进制数据。n 必须从 1 到 8,000。存储空间大小为实际输入数据长度 +4 个字节,而不是 n 个字节。输入的数据长度可能为 0 字节。在 SQL-92 中 varbinary 的同义词为 binary varying。
注释:如果在数据定义或变量声明语句中没有指定 n,默认长度为 1。如果没有用 CAST 函数指定 n,默认长度为 30。
2.由于使用了MVC结构,生成Model类的时候竟然不知道其对应类型,网上搜也没有结果,首先用了一个System.Data.SqlTypes.SqlBytes,后来误打误撞才发现竟然就是byte[]类型。
实现示例:
//1.首先将图片装换成字节数组 Bitmap btm = new Bitmap("C:/Users/Desktop/1.jpg"); MemoryStream ms = new MemoryStream(); btm.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); 这两句都可以 ms.Close(); try{ //2.往数据库里写图片数据 //先打开两个类库文件 SqlConnection con = new SqlConnection(); con.ConnectionString = "server=.;database=Test;uid=sa;pwd=123456"; con.Open(); SqlCommand com = new SqlCommand(); com.Connection = con; com.CommandType = CommandType.Text; com.CommandText = "insert into Map(Id,BitmapData) values(1,@photo)"; com.Parameters.AddWithValue("@photo", bytes); SqlDataReader dr = com.ExecuteReader();//执行SQL语句 dr.Close();//关闭执行 con.Close();//关闭数据库 //3.从数据库中取图片数据并显示 SqlConnection con = new SqlConnection(); con.ConnectionString = "server=.;database=Test;uid=sa;pwd=123456"; String sql = "select * from Map where Id=1"; SqlCommand cmd = new SqlCommand(sql, con); con.Open(); using (SqlDataReader dr = cmd.ExecuteReader()) { if (dr.Read()){ if (!dr.IsDBNull(1))//防止照片字段为空 { System.Data.SqlTypes.SqlBytes dataBytes = dr.GetSqlBytes(1); Image imge= Image.FromStream(dataBytes.Stream);//显示照片 pb.ImageLocation = null; pb.Image = null; pb.Image = imge; } } } con.Close();//关闭数据库 } catch (Exception) { throw; }
上述为测试示例,没有直接取byte[]类型,如果要转化成byte[]类型,可以用如下方法:
byte[] b=dr.GetSqlBytes(1).Value;
byte[] b1 = dr.GetSqlBytes(1).Buffer;