如何使用Apache File upload utils基于文件名设置最大文件大小

时间:2011-06-09 21:22:04

标签: java file-upload apache-commons

我有一个要求,我需要为不同的情况允许不同的最大文件大小。示例:允许5 MB用于恢复,仅3 MB用于转录。

我使用以下代码使用apache file upload utils上传文件。

        ServletFileUpload upload = new ServletFileUpload();
        upload.setSizeMax(500000000);
        upload.setProgressListener(aupl);
        FileItemIterator  iter = upload.getItemIterator(req);           

        while (iter.hasNext()) {
            FileItemStream item = iter.next();
            if (!item.isFormField()) {                  
                form_name = item.getFieldName();        
        InputStream stream = item.openStream();     
        FileOutputStream fop = new FileOutputStream(new File(temp_location));
        Streams.copy(stream, fop, true);                
            }             
        }                

我能找到该字段名称的唯一方法是使用item.getFieldName(),我只能在执行upload.getItemIterator后执行此操作,但必须在upload.getItemIterator之前设置setSizeMax(500 ..)叫做。

是否有解决此问题的方法?如果没有解决方案,您可以建议任何其他文件上传API来处理此问题。

由于

2 个答案:

答案 0 :(得分:2)

如果您反而循环遍历FileItem对象而不是FileItemStream对象,那么您需要做的就是设置一些常量最大值并将每个项目与适当的值进行比较。如果项目超过了大小,请适当处理(抛出新异常,删除文件,无论你想做什么),否则继续正常运行。

final long MAX_RESUME_SIZE = 5242880; // 5MB -> 5 * 1024 * 1024
final long MAX_TRANS_SIZE = 3145728; // 3MB -> 3 * 1024 * 1024

DiskFileItemFactory factory = new DiskFileItemFactory();
String fileDir = "your write-to location";
File dest = new File(fileDir);
if(!dest.isDirectory()){ dest.mkdir(); }
factory.setRepository(dest);
ServletFileUpload upload = new ServletFileUpload(factory);

for (FileItem item: upload.parseRequest(request)) { // request -> the HttpServletRequest
    if(!item.isFormField(){
        if(evaluateSize(item)){
            // handle as normal
        }else{
            // handle as too large
        }
    }
} // end while

private boolean evaluateSize(FileItem item){
    if(/* type is Resume */ && item.getSize() <= MAX_RESUME_SIZE){
        return true;
    }else if(/* type is Transcript */ && item.getSize() <= MAX_TRANS_SIZE){
        return true;
    }

    // assume too large
    return false;
}

当然,如果存在两种以上的文件类型,则必须添加更多逻辑,但是您可以看到在编写之前比较文件大小非常简单。

答案 1 :(得分:0)

假设非表单变量的数量有限(并且你可以强制执行),只需使用迭代器并使用包围流来在总字节数时抛出异常(存在大量基本计数器的实现 - 例如,参见commons-io)超过N,其中N在构造函数中作为限制提供。

eg

    long limit = 500000; // bytes
    long cumulativeSize=0;

while { 
    if (limit - cumulativeSize <=0) break; 
...
...
... // FileItem
    InputStream stream = item.openStream();
    stream = new LimiterStream(stream,100000);
    Streams.copy(stream,fop,true);
    FileOutputStream fop = new FileOutputStream(new File(temp_location));
    cumulativeSize += stream.getCount(); // you'd implement this too, to keep a running count
    catch (SizeExceededException e  )  {
            System.out.println("you exceeded the limit I set of "+e.getLimit(); // implemented 
            break;
     }
    ...
} // end while