Oracle中三种上载文件技术

时间:2007-06-15 来源: 作者: 【字体: 减小 增大收藏 | 投稿
  
Oracle中有多种方法可以向数据库或服务器文件系统上载文件,这里主要介绍如下三种:OracleHTTPServer(OHS)的mod_plsql模块提供通过web页面向数据库上载文件的功能;Oracle9iAS的标签库和Bean提供的文件上载功能;通过JDBC程序上载文件。

  一、OracleHTTPServer(OHS)的mod_plsql模块提供通过web页面向数据库上载文件的功能

  1.在文件上载的目标模式中建立文档访问表

CREATETABLE[table_name](
NAMEVARCHAR2(256)UNIQUENOTNULL,
MIME_TYPEVARCHAR2(128),
DOC_SIZENUMBER,
DAD_CHARSETVARCHAR2(128),
LAST_UPDATEDDATE,
CONTENT_TYPEVARCHAR2(128),
[content_column_name][content_column_type]
[,[content_column_name][content_column_type]]
);
  表中CONTENT_TYPE列为BLOB或longraw,但只能有一列。每个上载文件在表中单独占有一行,不能同时把多个文件上载到表中的同一行内,这是mod_plsql模块功能有限的地方。用下面和列建立文档表:Content_table。
财软联.盟.fs119.net


NAMEVARCHAR(128)UNIQUENOTNULL,
MIME_TYPEVARCHAR(128),
DOC_SIZENUMBER,
DAD_CHARSETVARCHAR(128),
LAST_UPDATEDDATE,
CONTENT_TYPEVARCHAR(128),
CONTENTLONGRAW,
BLOB_CONTENTBLOB;
  2.配置DAD的文档访问表

  启动数据库和OHS后,创建空白的数据库访问描述符。在"数据库访问描述符"页面的"网关使用文档表"信息向与此数据库访问描述符关联的数据库上载/下载文档。缺省情况下所有文档都将以BLOB上载。通过在LongRaw字段中指定以逗号分隔的文件扩展名,可以覆盖此缺省设置。此字段的*值将使所有文档以LongRaw上载。"文档访问过程"指定用于访问文档的虚拟路径。"文档访问过程"字段指定网关处理文档请求所调用的过程。这里指定缺省的文档表为content_table。

  3.提供文件上载页面,这里使用存储过程的形式上载和浏览、下载文件。 财 软联盟 fs119.net

CREATEORREPLACEPROCEDURE"ZYFILEUP"."IN_FILE"is
begin
htp.prn('
<html>
<head>
<title>Fileupload</title>
</head>
<bodybgcolor="#C0C0C0">
<formenctype="multipart/form-data"action="/pls/upfile/write_infos"method="POST">
<p><b><fontsize="5"color="#800080">指定上载文件</font></b></p>
<hr>
<p>
<b>标题:<textarearows="3"name="filetitle"cols="100"style="background-color:#008080;color:#FFFFFF"></textarea><br>
<b>类别:<inputtype="text"name="filesort"size="130"style="background-color:#008080;color:#FFFFFF"><br>
<b>作者:<inputtype="text"name="author"size="130"style="background-color:#008080;color:#FFFFFF"><br>
<b>小类:<inputtype="text"name="localsort"size="130"style="background-color:#008080;color:#FFFFFF"><br>
<b>摘要:<textarearows="5"name="abstract"cols="130"style="background-color:#008080;color:#FFFFFF"></textarea><br>
财.管家园.fs119.net

<b>文章1:<inputtype="file"name="up_file"size="110"style="background-color:#008080;color:#FFFFFF"><br>
<b>文章2:<inputtype="file"name="up_file"size="110"style="background-color:#008080;color:#FFFFFF"><br>
<b>文章3:<inputtype="file"name="up_file"size="110"style="background-color:#008080;color:#FFFFFF"><br>
<b>文章4:<inputtype="file"name="up_file"size="110"style="background-color:#008080;color:#FFFFFF"><br>
</b></b></b></b></b></b></b></b></b></b></p><hr><p><b>
<line>
<inputtype="submit"value="提交">
<inputtype="reset"value="全部重写">
</p>
</form>
</body>
</html>
');
end;
  4.提供上载文件浏览页面

  第3步提交的文件自动上载到文档表中,下面由存储过程WRITE_INFOS来记录上载的文件信息,实际上完全没必要,但这里做一比较。

CREATEORREPLACEPROCEDURE"ZYFILEUP"."WRITE_INFOS"( 财软联盟 fs119.net
filetitleinvarchar2,
up_fileinowa.vc_arr,
filesortinvarchar2,
authorinvarchar2,
abstractinvarchar2,
localsortinvarchar2
)is
inumber:=1;
begin
htp.htmlopen;
htp.headopen;
htp.title('FileUploaded');
htp.headclose;
htp.bodyopen;
htp.header(1,'UploadStatus');
whiletrueloop
begin
htp.prn('Uploaded'||up_file(i)||'successfully!');
htp.prn('<br>');
htp.prn('<ahref="/pls/upfile/downfile?upfilename=');
htp.prn(utl_url.escape(up_file(i),true,'GBK'));
htp.prn('"target="_blank">Openthisfile!</a>');
htp.prn('<br>');
INSERTINTO"ZYFILEUP"."FILE_TABLE"
values(filetitle,up_file(i),filesort,author,sysdate(),abstract,localsort);
commit;
i:=i1;
exception
whenno_data_foundthenexit;
end;
endloop;
htp.line;
htp.print('Uploadedsuccessfully!');
htp.bodyclose;
htp.htmlclose;
end;
  查阅文档表后会发现,文件已经上载了,但文档表的上载时间有错误,与上载记录中的系统时间不符,这可能是该功能的一个BUG,如果谁有解决此问题的办法或软件补丁,请告诉我。
财软 联盟 fs119.net


  5.为上载文件提供页面浏览功能

CREATEORREPLACEPROCEDURE"ZYFILEUP"."DOWNFILE"(upfilename
invarchar2)
is
mimetypevarchar2(100);
myblobblob;
begin
selectmime_type,blob_contentintomimetype,myblob
fromzyfileup.content_tablewherename=upfilename;
owa_util.mime_header(mimetype,true);
sys.wpg_docload.download_file(myblob);
end;


  这样可以通过Web浏览器根据上载文件的mime_type类型浏览文件了。

  这种上载文件的办法最为简单,可以支持中文文件名,支持客户端文件上载和下载,可以自动识别文件类型和计算文件大小。 财管家园 fs119.net

财软.联盟.fs119.net

财管家,园,fs119.net


财管家园 fs119.net

财 管家园 fs119.net

  二、Oracle9iAS的标签库和Bean提供的文件上载功能

  Oracledevelopersuit9i中的Jdeveloper9031提供通过标签库上载文件的方法,下面的例子中in_file.jsp文件提供上载表单,up_file.jsp列出上载文件列表,dn_file.jsp文件为下载刚才上载的文件。该方法使用图形编辑器,简单可行,但不支持中文文件名,可实现客户端文件上载和下载。

  如下为in_file.jsp的源程序:

<%@tagliburi="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/fileaccess.tld"
prefix="fileaccess"%>
<%@pagelanguage="java"import="java.io.*"contentType="text/html"%>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/HTML;charset=gb2312">
<title>jdbcuploadanddownloadblob</title>
</head>
<body>
<fileaccess:httpUploadForm
formsAction="up_file.jsp"
maxFiles="5"fileNameSize="100"
maxFileNameSize="150"submitButtonText="send">

财,软联盟,fs119.net

</fileaccess:httpUploadForm>
</body></html>
  up_file.jsp的源程序:

<%@tagliburi="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/sqltaglib.tld"prefix="database"%>
<%@tagliburi="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/fileaccess.tld"prefix="fileaccess"%>
<%@pagelanguage="java"contentType="text/html;charset=gb2312"%>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/HTML;charset=gb2312">
<title>jdbcuploadanddownloadblob</title>
</head>
<body>
<database:dbOpenuser="zy"password="zy"
URL="jdbc:oracle:thin:@db92:1521:cf92"commitOnClose="true">
<fileaccess:httpUpload
destination="zy_blob"
destinationType="database"
table="blob_table">
</fileaccess:httpUpload>
</database:dbOpen>
Done!
<ahref="dn_file.jsp">下载!</a>
</body></html>
  dn_file.jsp的源程序: 财管家.园.fs119.net

<%@tagliburi="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/fileaccess.tld"prefix="fileaccess"%>
<%@tagliburi="http://xmlns.oracle.com/j2ee/jsp/tld/ojsp/sqltaglib.tld"prefix="database"%>
<%@pagecontentType="text/html;charset=GBK"%>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=GBK">
</head>
<body>
<database:dbOpenuser="zy"password="zy"
URL="jdbc:oracle:thin:@db92:1521:cf92">
<fileaccess:httpDownloadsource="*"servletPath="/"
sourceType="database"table="blob_table">
</fileaccess:httpDownload>
</database:dbOpen>
Downloaddone!
</body>
</html>
  三、通过JDBC实现文件上载和下载

  通过把文件上载到BLOB或CLOB列实现文件上载,但此法不支持客户端文件上载,所以局限性很大,通过JDBC实现的下载功能也只是在服务器的本地下载(下载程序没有列出),所以这种方法仅作为一项技术参考可以,没有太大实用价值。

财管家.园.fs119.net



  Blob_in_stream.jsp程序如下:

<%@pagesession="true"language="java"%>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/HTML;charset=gb2312">
<title>jdbcuploadanddownloadblob</title>
</head>
<body>
<FORMaction="blob_w_stream.jsp"method="POST">
<p>文件Filetoupload:<INPUTtype="file"name="up_file"><br>
<p><INPUTtype="submit">
</FORM>
</body>
</html>
  Blob_w_stream.jsp程序如下:

<%@pagesession="true"language="java"contentType="text/html;charset=gb2312"%>
<%@pageimport="java.sql.*"%>
<%@pageimport="java.io.*"%>
<%@pageimport="oracle.jdbc.driver.*"%>
<%@pageimport="oracle.sql.*"%>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/HTML;charset=gb2312">
<title>jdbcuploadanddownloadblob</title> 财.软联盟.fs119.net
</head>
<body>
<%
Stringuploadfile=request.getParameter("up_file");
//Inputformdon'thaveENCTYPE="multipart/form-data"clause,elseinput
//filenamewillNULL!Getfilenamefrominputform.
FilebinaryFile=newFile(uploadfile);
Readerchar_stream=clobtext.getCharacterStream();
char[]char_array=newchar[length];
intchars_read=char_stream.read(char_array,0,length);
out.println(char_array);
out.println();
out.write();
InputstreamasciiChar_stream=clobtext.getAsciiStream();
byte[]asciiChar_array=newbyte[length];
intasciiChar_read=asciiChar_stream.read(asciiChar_array,0,length);
//OrFilebinaryFile=newFile("c:\\cf\\a.doc");pointtoc:\cf\a.doc.
FileInputStreaminstream=newFileInputStream(binaryFile);
%>
<p>filenameis:<%=uploadfile%>
<%
Class.forName("oracle.jdbc.OracleDriver").newInstance();
StringconnStr="jdbc:oracle:thin:@db92:1521:cf92";
Stringuser="zy";
Stringpassword="zy";
Connectionconn=DriverManager.getConnection(connStr,user,password); 财管,家园,fs119.net
conn.setAutoCommit(false);
Statementstmt=conn.createStatement();
stmt.execute("UPDATEZY.BLOB_TABLESETDATA=EMPTY_BLOB()WHEREFILENAME='Concepts.pdf'");
conn.commit();
//mustnulltheblobdatacolumn,elseifsizeofinsertingfilelessthan
//existingblobfile,thennewinsertfileformaterroroccur!Newblobfiledon't
//overwriteoldblobcolumndata!
Stringcmd="SELECTDATAFROMZY.BLOB_TABLEWHEREFILENAME='Concepts.pdf'forupdate";
ResultSetrset=stmt.executeQuery(cmd);
BLOBblob;
rset.next();//must.elseoccurerror"don'tcallResultSet.next()"
blob=((OracleResultSet)rset).getBLOB(1);
//mustexplicit!dontlocateinlogicalblock.forexample,locateinIF...ITEN.
OutputStreamoutstream=blob.getBinaryOutputStream();
intsize=blob.getBufferSize();
%>
<p>buffersizeis:<%=size%>
<%
byte[]buffer=newbyte[102400];
//Ordirect102400insteadofvariablesize!
//Performancetips!size=24396.
intlength=-1;
while((length=instream.read(buffer))!=-1)
outstream.write(buffer,0,length);
instream.close(); 财管 家园 fs119.net
outstream.close();
conn.commit();//mustexplicitcommit!IfBFILE,thenautocommit.
conn.close();
%>
<p>Uploadfileisdown!
</body>
</html>

财.软联盟.fs119.net

财软联.盟.fs119.net

财管 家园 fs119.net


上一篇:Oracle建立二进制文件索引的方法
下一篇:Oracle数据操作和控制语言详解

精品课程推荐