以前處理上傳或者下載的時候,我一般會將文件直接存取到服務器的文件系統中,而這樣做唯一的好處就是開發起來容易,而現在這種方式越來越不適合一些重要和大型的項目了,因爲在做系統備份時還要做額外的文件備份,而災難恢復更是不好實現。所以現在還是比較提倡使用Oracle中的Blob字段作爲存取手段來應付大容量數據。
在網上找了一些介紹的帖子,基本上的方法都是一樣,無非是分成兩個步驟:
1. 插入一條記錄,Blob自短暫時插入空值: empty_blob();
2. 從數據庫當中select出這條記錄,鎖住該行然後插入二進制數組内容( select content from tablename where id=? for update);
我最近做的一個項目當中用到的上傳也是基於該法則,但是不同于一般的是我們將JDBC的部分剝離掉了,剩下的只有對字符串的處理以及二進制文件的處理,而其中所傳的參數完全是綁定到Model中的,Model就是VO,只要大家懂得其中的模式是很好理解的,下面我貼出一些關鍵代碼:
/*這裡主要是將傳入的文件進行處理,然後以 ByteArrayOutputStream 的形式寫入
WebUploadForm[] form = super.getUploadFiles(request);
if (form != null && form.length > 0) {
String file_name = form[0].getFileName();
if (file_name.indexOf("/") > -1) {
file_name = file_name.substring(file_name.lastIndexOf("/") + 1);
}
if (file_name.indexOf("//") > -1) {
file_name = file_name.substring(file_name.lastIndexOf("//") + 1);
}
String ext = file_name.substring(file_name.lastIndexOf(".") + 1);
InputStream file_in = form[0].getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ( (bytesRead = file_in.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
file_in.close();
AttachModel aModel = new AttachModel();
aModel.setId(UIDGenerator.generateUUID());
aModel.setFileName(file_name);
aModel.setFileType(StringUtils.toString(ext).toUpperCase());
aModel.setParentId(parentId);
aModel.setFileContent(bos.toByteArray());
facade.addAttach(aModel);
/*調用addAttach(aModel)方法,具體實現*/
public void addAttach(AttachModel aModel) throws DaoException{
try{
sqlExecutor.setDataSource(JNDINames.ARMY_DS);
sqlExecutor.clearParams();
StringBuffer sb = new StringBuffer();
sb.append("insert into MY_ATTACH(ID,FILE_NAME,FILE_TYPE,PARENT_ID,SEQ,FILE_CONTENT)");
sb.append(" values(#{id},#{fileName},#{fileType},#{parentId}");
sb.append(",nvl((select max(seq) from MY_ATTACH where PARENT_ID = #{parentId} group by PARENT_ID),0)+1");
sb.append(",empty_blob())");
sqlExecutor.exec(sb.toString(),aModel);
if(aModel.getFileContent()!=null){
sqlExecutor.clearParams();
StringBuffer sb_update = new StringBuffer();
sb_update.append("select file_content from MY_ATTACH where ID = #{id} for update ");
//sqlExecutor.addParam(aModel.getId());
/////////////////////////////////////////////////////////////////
SQLResults result = sqlExecutor.execQuery(sb_update.toString(),aModel);
/////////////////////////////////////////////////////////////////
if(result.next()){
Blob content = result.getBlob("FILE_CONTENT");
InputStream is = new ByteArrayInputStream(aModel.getFileContent());
//System.out.println("----------aModel.getFileContent()--------------"+aModel.getFileContent());
OutputStream os = ( (weblogic.jdbc.common.OracleBlob)content).getBinaryOutputStream();
byte[] inBytes = new byte[aModel.getFileContent().length];
System.out.println(aModel.getFileContent().length);
int numBytes = is.read(inBytes);
while(numBytes>0){
os.write(inBytes,0,numBytes);
numBytes = is.read(inBytes);
}
os.flush();
os.close();
is.close();
}
}
}catch(Exception jdbce){
log.throwing(jdbce);
throw new DaoException(jdbce);
}finally{
sqlExecutor.close();
}
}
博客指出将文件直接存取到服务器文件系统不适用于重要和大型项目,提倡使用Oracle中的Blob字段存取大容量数据。介绍了基本步骤,并给出关键代码,包括文件处理、插入记录、更新Blob字段等,还处理了可能出现的异常。
6597

被折叠的 条评论
为什么被折叠?



