1 MySQL存储大容量的二进制文件的格式是blob,其实除了图片还可以存别的
2 要向数据库存储二进制的文件一定要把要存储的数据转换成二进制流
废话就不多说了,大家看看代码很容易明白,先来看一个app程序,当然首先您要在数据库中先建立一个用于保存图片的表和相应的列,数据格式为blob
packagecom.lizhe; importJava.io.*; importjava.sql.*; publicclassPutImg{ publicvoidputimg(){ try{ Class.forName("org.gjt.mm.mysql.Driver").newInstance(); Stringurl="JDBC:mysql://localhost/img?user=root&password=root&useUnicode=true&characterEncoding=gbk"; Connectionconn=DriverManager.getConnection(url); Statementstmt=conn.createStatement(); //stmt.execute("insertintoimgt(id)values(5)"); stmt.close(); PreparedStatementpstmt=null; Stringsql=""; Filefile=newFile("c:log.jpg"); InputStreamphotoStream=newFileInputStream(file); //sql="UPDATEimgtSETimg=?"; sql="INSERTINTOimgtable(img)VALUES(?)"; pstmt=conn.prepareStatement(sql); pstmt.setBinaryStream(1,photoStream,(int)file.length()); pstmt.executeUpdate(); pstmt.close(); conn.close(); }catch(Exceptione){ e.printStackTrace(); } } publicstaticvoidmain(Stringargs[]){ PutImgpi=newPutImg(); pi.putimg(); } } |
InputStream photoStream = new FileInputStream(file);
可以很清楚的看到我们首先把一个图片文件(当然也可以是别的什么文件)转换成了一个二进制输入流
pstmt.setBinaryStream(1,photoStream,(int)file.length()); |
这个方法建议大家去查一下API文档,第一个参数是通配符位置没的说,第二个参数是流,这和以往的string类型的参数不太一样,我刚看到的时候也觉得豁然开朗了,但是到这里还没完,不同于以往的字符串参数,这里我们还需要第三个参数来设置这个流的长度,这里也就是这个文件的长度,导出数据库中的sql,一切都清楚了
INSERT INTO `m_diy` VALUES (2,? JFIF HH?? ExifMM* b j ( 1 r 2 ?i H H Adobe Photoshop CS Windows2007:03:18 23:08:15 ? ??? ? ........等等
其实就是将文件先转换成了二进制的流,然后插入到了sql语言中,向数据库写入了很长很长的一段sql语句
然后我们再来写一个app程序将这个文件读出来,存储成一个图片文件
packagecom.lizhe; importJava.io.*; importjava.sql.*; classGetImg{ privatestaticfinalStringURL="JDBC:MySQL://localhost/img?user=root&password =root&useUnicode=true&characterEncoding=gbk"; privateConnectionconn=null; privatePreparedStatementpstmt=null; privateResultSetrs=null; privateFilefile=null; publicvoidblobRead(Stringoutfile,intpicID)throwsException{ FileOutputStreamfos=null; InputStreamis=null; byte[]Buffer=newbyte[4096]; try{ Class.forName("org.gjt.mm.mysql.Driver").newInstance(); conn=DriverManager.getConnection(URL); pstmt=conn.prepareStatement("selectimgfromimgtwhereid=?"); pstmt.setInt(1,picID);//传入要取的图片的ID rs=pstmt.executeQuery(); rs.next(); file=newFile(outfile); if(!file.exists()){ file.createNewFile();//如果文件不存在,则创建 } fos=newFileOutputStream(file); is=rs.getBinaryStream("img"); intsize=0; while((size=is.read(Buffer))!=-1){ //System.out.println(size); fos.write(Buffer,0,size); } }catch(Exceptione){ System.out.println(e.getMessage()); }finally{ //关闭用到的资源 fos.close(); rs.close(); pstmt.close(); conn.close(); } } publicstaticvoidmain(String[]args){ try{ GetImggi=newGetImg(); gi.blobRead("c:/getimgs/1.jpg",5); }catch(Exceptione){ System.out.println("[Mainfuncerror:]"+e.getMessage()); } } } |
这里需要注意的是
is=rs.getBinaryStream("img"); |
img是数据库中相应的列名,其实和rs.getString()方法差不多,只不过这个方法是读取二进制流的
最后在帖两个bs系统上用的文件给大家参考
通过Struts的action向数据库写入二进制图片
/* *GeneratedbyMyEclipseStruts *Templatepath:templates/Java/JavaClass.vtl */ packagecom.lizhe.struts.action; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileNotFoundException; importjava.io.IOException; importjava.io.InputStream; importjava.sql.Connection; importjava.sql.DriverManager; importjava.sql.PreparedStatement; importjava.sql.Statement; importjavax.Servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importorg.apache.struts.action.Action; importorg.apache.struts.action.ActionForm; importorg.apache.struts.action.ActionForward; importorg.apache.struts.action.ActionMapping; importorg.apache.struts.upload.FormFile; importcom.lizhe.struts.form.UpimgForm; /** *MyEclipseStruts *Creationdate:05-18-2007 * *XDocletdefinition: *@struts.actionpath="/upimg"name="upimgForm"input="/userhomepage.JSP" *@struts.action-forwardname="userhome"path="/userhomepage.jsp"redirect="true"contextRelative="true" */ publicclassUpimgActionextendsAction{ /* *GeneratedMethods */ /** *Methodexecute *@parammapping *@paramform *@paramrequest *@paramresponse *@returnActionForward *@throwsIOException *@throwsFileNotFoundException */ publicActionForwardexecute(ActionMappingmapping,ActionFormform, HttpServletRequestrequest,HttpServletResponseresponse)throwsFileNotFoundException,IOException{ UpimgFormupimgForm=(UpimgForm)form;//TODOAuto-generatedmethodstub FormFilefile=upimgForm.getFile(); InputStreamis=file.getInputStream(); try{ Class.forName("org.gjt.mm.MySQL.Driver").newInstance(); Stringurl="JDBC:mysql://localhost/blog?user=root&password=root&useUnicode=true&characterEncoding=gb2312"; Connectionconn=DriverManager.getConnection(url); Statementstmt=conn.createStatement(); //stmt.execute("insert into img(id) values (5)"); stmt.close(); PreparedStatementpstmt=null; Stringsql=""; //Filefile=newFile("c:log.jpg"); //InputStreamphotoStream=newFileInputStream(file); //sql=" UPDATE imgt SET img = ? "; sql="INSERTINTOimg(img)VALUES(?)"; pstmt=conn.prepareStatement(sql); pstmt.setBinaryStream(1,is,(int)file.getFileSize()); pstmt.executeUpdate(); pstmt.close(); conn.close(); }catch(Exceptione){ e.printStackTrace(); } returnmapping.findForward("userhomepage"); } } |
和app的方式几乎是一样的
第二个文件是通过jsp将数据库中的图片显示在页面上
这个有些不同
<%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.sql.*" %> <%@ page import="java.util.*"%> <%@ page import="java.text.*"%> <%@ page import="java.io.*"%> <%@ page import="java.awt.*"%> <html> <body> <% Class.forName("org.gjt.mm.mysql.Driver").newInstance(); Stringurl="jdbc:mysql://localhost/img?user=root&password=root"; Connection con = DriverManager.getConnection(url); String sql = "select * from imgtwhereid=5"; Statementstmt=con.createStatement(); ResultSetrs=stmt.executeQuery(sql); if(rs.next()){ InputStreamin=rs.getBinaryStream("img"); ServletOutputStreamop=response.getOutputStream(); intlen; byte[]buf=newbyte[1024]; while((len=in.read(buf))!=-1){ op.write(buf,0,len); } op.close(); in.close(); } rs.close(); stmt.close(); con.close(); %> </body> </html> |