您的位置:首页 > 数据库

将图片保存到数据库的处理

2009-08-24 15:27 155 查看
其实将图片保存在数据库中不外乎两种方式。

1,图片文件保存在硬盘上,数据库中负责记录路径(不管是绝对路径还是相对路径)。

2,图片直接以二进制的形式保存在数据库中。

两者各有优势

1,存储的文件显而易见,而且实现方便。当然掉包也方便。

麻烦的地方就是管理,比如路径以及关联内容的识别管理。程序移植不变。

2,管理方便。全sql管理。图片文件及其相关的内容可以方便检索和识别。

不便就是写程序麻烦一点。当然这一点在现在来说,也是不值得一提。封装好的库包不需要再动脑筋想事。

还有就是当图片文件大和非常多的时候,将可能严重影响数据库的性能。

当然还有很多异同都可以自己体会,具体选择哪种方式,依据自身情况而定。

下面说说二进制保存的例子。

在将图片文件添加到数据库的时候,需要预处理一下。
1,将图片文件转换成二进制
2, 对二进制分析,提取文件数据,剔除头部和尾部
3, 然后就可以将二进制数据保存在对应的image类型的字段中了。

读取图片数据的时候,指定一下文件格式。图片就还原了。

这是一段n久前写的vb代码:

这段是页面上传图片文件的处理过程。request是form过来的。

formsize=request.totalbytes
if formsize>500000 then
response.write "<mce:script language='javascript'><!--
alert('只允许不大于500k的图片上传');
// --></mce:script>"
response.write "<mce:script language='javascript'><!--
history.go(-1);
// --></mce:script>"
end if
formdata=request.binaryread(formsize)
bncrlf=chrb(13) & chrb(10)
divider=leftb(formdata,clng(instrb(formdata,bncrlf))-1)
datastart=instrb(formdata,bncrlf & bncrlf)+4
dataend=instrb(datastart+1,formdata,divider)-datastart
mydata=midb(formdata,datastart,dataend)

Sql="Select * From test_img Where id =2"
Rs.open sql,conn,1,3
'追加数据到数据库
Rs.AddNew
Rs("img").appendchunk mydata
Rs.Update
'闭和释放对象
Rs.close
'conn.close


又兴趣的可以研究下,不进行处理,数据库中的相应字段存放的内容是什么,然后在看看处理后,字段存放的二进制代码内容又有什么差异。

读取的时候:
function getSignature(id)
set rs=server.createobject("ADODB.recordset")
sql="select * from test_img where id=" & id
rs.open sql,conn,1,1
'Response.ContentType = "text/html" '显示图片的格式也可以用
Response.ContentType = "image/gif"' 以gif显示
'Response.ContentType = "image/jpg" '以jpg显示
Response.BinaryWrite rs("img") '显示图片
rs.close
end function

Java版本的处理过程。

File file = new File("img.gif");
FileInputStream fis;

fis = new FileInputStream(file);
pstmt = conn
.prepareStatement("insert   into   tbl_image   values   (?,?)");
pstmt.setString(1, file.getName());
pstmt.setBinaryStream(2, fis, (int)file.length());
pstmt.executeUpdate();
pstmt.close();
fis.close();


这里需要注意 pstmt.setBinaryStream(2,fis,(int)file.length) 需要加(int)。 很奇怪的。

没有强制转换,居然能报错。虽然file.length()返回的是long。抑或sun还需要在加个函数setBinaryStream(int,InputStream,long)重载一下。

Exception in thread "main" java.lang.AbstractMethodError: com.microsoft.jdbc.base.BasePreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V

为什么这段Java代码没有预处理呢,只能归功于java.sql中已经实现了,我们就随便用就行了。

再补充一个例子的二进制文件:

这个是图片文件存储到数据库中的二进制表示形式:

0x47494638396123001E00E60000000000FFFFFFFEFEFEFDFDFDF7F7F7F2F2F2EFEFEFEEEEEEEDEDEDEAEAEADEDEDEDBDBDBDADADAD9D9D9CECECECBCBCBC8C8C8C5C5C5B8B8B8B7B7B7B2B2B2AFAFAFA7A7A7A6A6A6A1A1A1A0A0A09F9F9F9999999494949393938F8F8F8D8D8D8C8C8C8989898787878181817C7C7C7878787474747373736F6F6F6C6C6C6767676666666161615F5F5F5C5C5C5B5B5B5A5A5A5959595858585454545353534D4D4D4C4C4C4040403C3C3C3636362E2E2E2D2D2D2929292727272020201F1F1F1D1D1D1818181616161414141313130F0F0F0C0C0C0B0B0B0A0A0A080808070707040404FFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021F9040100004C002C0000000023001E000007FF804C82838485868788018A8B8C8D8E8F8D4C90014100963593990192900F002632009A939C8D968A1F01A2A38FA58CA7130036AC90AE96B7AAABB48AA79BAA11B7A296088D1ABA900018AB4CC1129A431E9A0201268A4CC4B74999000D001093410139D6BC3014058F03C29617C8A2EABE013FBD002A0C1D8A30B8C78C3EA707A25C2D0AC60BC00E01FC3E04034042119078A67ABDA2C148C929002044F1083003E2A21112070240F2CA920E61B94A780C702264417E1B2CAD5807C085058F2015469CC12F17800A3E03C48078AAC7B18B1C2E6E28583003011C441515E93975E1234B2202A45899AB51885B0E5C2E4A5A5060001D464C0D6C3129C11214013C0C00302B2422AD23AA144D300B6081C85DEB02DC30FBE2D52E05AB84F1DDE5481791B98D193762C1A8C162C9A42263AEA5F99101C9821A61DADC2A10003B


而在本地磁盘中,文件的二进制表示形式为:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐