关于SmartUpload上传文件至服务器目录问题:如何在上传之后释放文件流所耗内存?

alphazhao 2004-07-02 11:54:00
兄弟目前遇到一个问题,由于系统各个模块都有用到附件上传。但当系统中用户足够多的时候,倘若大家都上传附件,则很容易造成进程堵塞。
我检查了一下使用SmartUpload的上传代码,具体相关处理代码如下:
<jsp:useBean id="myUpload" scope="page" class="com.jspsmart.upload.SmartUpload" />
<%
myUpload.initialize(pageContext);
myUpload.upload();
java.util.Enumeration e = myUpload.getRequest().getParameterNames();
String path=request.getRealPath("."); //文件路径
path = path.substring(0,path.length()-1)+"g/documentsave/gongcheng";
//........相关变量处理
try {
com.jspsmart.upload.File myFile = myUpload.getFiles().getFile(0);
FileName = myFile.getFileName();
FileName = new String(FileName.getBytes("iso-8859-1"),"GBK");
SlaveSize = myFile.getSize();
String ReName = System.currentTimeMillis()+SlaveSize+"."+myFile.getFileExt(); //文件重命名
String alphaPt = path+"/"+ReName;
myFile.saveAs(alphaPt);//上传保存文件
} catch (Exception er) {
out.println(er.toString());
}
%>
其中并无关于上传完毕后的内存释放处理。
因为SmartUpload上传是先将文件流读到内存中,再转换写入服务器目录下,而上传完毕后并未主动将所用内存释放,所以本人认为进程堵塞的主要原因便是在此。
我检查了SmartUpload原文件,期间并没有类似close等释放对象的方法。由于本人并没有关于二进制文件流的释放处理经验,不知道哪位大哥可以提供类似的处理?
...全文
660 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyfoxs 2005-04-09
  • 打赏
  • 举报
回复
mark
newste 2005-04-07
  • 打赏
  • 举报
回复
mark
mahf 2005-04-06
  • 打赏
  • 举报
回复
mark
hykwolf 2004-07-06
  • 打赏
  • 举报
回复
你可以把smartupload的组件改为对commons-fileupload组件的引用,改一些方法应该就可以了吧,这样楼主就不需要改自己的程序了,只要修改smartupload,然它内部调用其他组件完成
hykwolf 2004-07-06
  • 打赏
  • 举报
回复
smartupload实现的方式不好,只能用于小文件上串,因为它吧整个request流都写入一个byte[]了,然后在处理这些byte[],所以,当多用户同时上传的时候势必造成了内存资源用的情况,建议搂主忍痛割爱,放弃smartupload,或者修改其它非内存读取式的组件,他它的方法改的和smartupload兼容,不过这个工作量比换组件工作量更大,看楼主取舍了,建立还是忍了换吧
eaglecoody 2004-07-06
  • 打赏
  • 举报
回复
fileupload里面倒有这方面的优化,就是只写入4KB入内存,其他放在硬盘上面
楼主如果 知道方法,麻烦贴一下。有 知道的 也 麻烦给个例子。。
up
cckylin 2004-07-06
  • 打赏
  • 举报
回复
我现在想知道,smartupload最后到底释放了吗?
alphazhao 2004-07-06
  • 打赏
  • 举报
回复
共享本人修改后的相应上传处理bean的方法如下:(注意,我后面数据库处理是放入一条附件记录罢了)

public void doFileUpload(HttpServletRequest request,String path,String savedir,String flag,String iorCID) {
//比如传入(rquest,,"111","2004","niandu")
Connection Conn = null;
try {
HttpSession session = request.getSession();
OperatorloginObject userOb = (OperatorloginObject)session.getAttribute("OperatorloginObject");
String account = userOb.getAccount();
String unitid = userOb.getUnitid();
userOb = null;
session = null;
String sqlStr = "";
boolean canUpload = true;
//String path = pageContext.getServletContext().getRealPath("."); //文件路径
path = path.substring(0,path.length()-1);
String filePath = path+"g\\documentsave\\"+savedir;
String saveAs = filePath+"\\";
String fileTemp = path+"g\\documentsave\\temp";
String threeSql = "";//三个界面input对象取值
//AIX服务器上是
//String filePath = path+"g/documentsave/"+savedir;
//String saveAs = filePath+"/";
//String fileTemp = path+"g/documentsave/temp";
String fileName = "";
String reName = "";
long SlaveSize = 0;
DiskFileUpload fu = new DiskFileUpload();
fu.setSizeMax(5242880);
fu.setSizeThreshold(4*1024);//内存内存放4KB
fu.setRepositoryPath(fileTemp);
List fileItems = fu.parseRequest(request);
Iterator iter = fileItems.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem)iter.next();
if(!item.isFormField()) {//是文件流
fileName = item.getName();
SlaveSize = item.getSize();
if((fileName==null||fileName.equals("")) && SlaveSize==0) {
canUpload = false;
break;
}
//System.out.println("开始="+fileName);
//开始处理真实文件名
String[] possibleSeparator = new String[] { "/", "\\"};
for( int i=0; i<possibleSeparator.length; i++ ) {
String separator = possibleSeparator[i];
int index = fileName.lastIndexOf(separator);
if(index!=-1) {
fileName = fileName.substring(index+separator.length());
break;
}
}
//System.out.println("真实="+fileName);
//取得文件类型
String fileExt = "";
int index = fileName.lastIndexOf(".");
if(index!=-1) {
fileExt = fileName.substring(index);
}
//System.out.println("类型="+fileExt);
//重命名
reName = unitid+flag+iorCID+System.currentTimeMillis()+fileExt; //文件重命名
//System.out.println("保存="+saveAs+reName);
item.write(new File(saveAs+reName));
}
else {
threeSql = threeSql+"'"+item.getString()+"',";
}
//注意删除临时文件
item.delete();
item = null;
iter.remove();
}
//注意释放
iter = null;
fileItems.clear();
fileItems = null;
fu = null;
//System.out.println("threeSql="+threeSql);
if(canUpload) {
sqlStr = "insert into Documents (ID,Flag,IorCID,DocumentName,NameDocument,DocumentSize,DocumentPath,"
+"DocumentCode,DocumentDescribe,DocumentType,DocumentUpDate,UpCounter) values "
+"(DOCUMENTS_ID.nextval,"+flag+","+iorCID+",'"+fileName+"','"+reName+"',"+SlaveSize+",'"+filePath+"',"
+threeSql+"sysDate,'"+account+"')";
//System.out.println("sqlStr="+sqlStr);
Conn = sqlBean.getConnection();
Statement stmt = Conn.createStatement();
stmt.executeUpdate(sqlStr);
stmt.close();
stmt = null;
}
}
catch (Exception ex) {
System.out.println("上传文件后台提示:"+ex.toString());
}
finally {
try {
if(Conn != null) {
Conn.close();
Conn = null;
}
}
catch (Exception ex) {
System.out.println("Closing conn error!");
ex.printStackTrace();
}
}
}
alphazhao 2004-07-06
  • 打赏
  • 举报
回复
根据各位兄弟建议,在下改用fileupload组件,捣弄了半天,总算明白过来,其实并不是很复杂,只不过在AIX系统下还有些问题罢了。
另外,我仔细看了看,fileupload不但内存消耗小,而且释放机制也还行,就是上传速度稍微慢了些,不过也罢,为了稳定……
cckylin 2004-07-06
  • 打赏
  • 举报
回复
如果最后还是释放了应该可以的!关注这个问题
cckylin 2004-07-06
  • 打赏
  • 举报
回复
请问楼主你发现这样的情况是有多少人在上传,内存丢了吗?还是用户传完了以后又释放了?
hykwolf 2004-07-06
  • 打赏
  • 举报
回复
commons-fileupload也是全部读到内存里处理的?我看都楼上有位说的使用的临时文件.
当然开始的时候肯定要用内存来缓冲数据的了
lionzhf 2004-07-06
  • 打赏
  • 举报
回复
我也在弄这个东东,尝试各种方式制空,但是还是不行,你连续上传5张以上,整个网站就变得很慢很慢了!
cckylin 2004-07-06
  • 打赏
  • 举报
回复
smartupload与commons-fileupload不都是在内存里处理的吗,不一样占内存吗?请高手指点一二!
朋友别哭 2004-07-05
  • 打赏
  • 举报
回复
帮你UP
hbwjz 2004-07-05
  • 打赏
  • 举报
回复
myUpload=null;建议你使用完一个对象之后就将其置为null
hbwjz 2004-07-05
  • 打赏
  • 举报
回复
应该是你在 myFile.saveAs(alphaPt);//上传保存文件
完了之后,把myFile = null;就可以了吧,我一直都是这样,也没感觉有什么问题阿
alphazhao 2004-07-05
  • 打赏
  • 举报
回复
大佬
没有时间去研究fileupload组件吖
有没有直接优化smartupload组件的代码?就是释放内存方面的优化,以减轻服务器的压力的那种
AgathaZ 2004-07-05
  • 打赏
  • 举报
回复
我是把上传后的文件放到数据库,设字段为blob型
然后
byte[] bytArray = new byte[file.getSize()];
for (int i= 0 ;i<file.getSize();i++) {
bytArray[i] = file.getBinaryData(i);
}
ci.setImage(bytArray);
这样可能没有耗多大内存。
alphazhao 2004-07-05
  • 打赏
  • 举报
回复
没有这么简单
置空我早尝试过了,没有太大的作用
另外我发现内存消耗主要原因是在于若上传人数太多,所有文件数据都会写入内存,从而造成大批量消耗
fileupload里面倒有这方面的优化,就是只写入4KB入内存,其他放在硬盘上面,可惜不知道如何实现,找不到合适的例子参考吖
加载更多回复(5)

81,095

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧