java 如何使用 Apache 文件上传工具根据文件名设置最大文件大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6299465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:16:06  来源:igfitidea点击:

How to set maximum file size based on file name using Apache File upload utils

javafile-uploadapache-commons

提问by Adithya Puram

I have a requirement where I need to allow different maximum-file-sizes for different cases. Example: Allow 5 MB for resume, only 3 MB for transcripts.

我有一个要求,我需要为不同的情况允许不同的最大文件大小。示例:允许 5 MB 用于简历,仅允许 3 MB 用于成绩单。

I am using the following code to upload the file using apache file upload utils.

我正在使用以下代码使用 apache 文件上传工具上传文件。

        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);                
            }             
        }                

The only way I can find the name of the field is using item.getFieldName() and I can do that only after doing upload.getItemIterator, but setSizeMax(500..) has to be set on upload before upload.getItemIterator is called.

我可以找到字段名称的唯一方法是使用 item.getFieldName() 并且我只能在执行 upload.getItemIterator 之后才能这样做,但是 setSizeMax(500..) 必须在调用 upload.getItemIterator 之前在上传时设置。

Is there a work around for this problem? If there is no solution, can you suggest any other File Upload API which handles this problem.

这个问题有解决方法吗?如果没有解决方案,您能否建议任何其他处理此问题的文件上传 API。

Thanks

谢谢

回答by Finni McFinger

If you instead loop through FileItem object instead of FileItemStream objects, all you need to do is set some constant max size values and compare each item to the appropriate value. If an item exceeds the size, handle it appropriately (throw new exception, trash the file, whatever you want to do), otherwise continue running as normal.

如果您改为遍历 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;
}

Granted, you will have to add more logic if there is more than the two types of file, but you can see it is very simple to compare your file sizes before having to write.

当然,如果文件类型多于两种类型,您将不得不添加更多逻辑,但是您可以看到在必须写入之前比较文件大小非常简单。

回答by MJB

Assuming the number of non form variables is limited (and you could enforce that), just use the iterator and use a wrapping around the stream to throw an exception when the total number of bytes (plenty of implementations of basic counters exist - see commons-io for example) exceed N, where N is supplied as a limit in the constructor.

假设非表单变量的数量是有限的(并且您可以强制执行),只需使用迭代器并使用环绕流的包装在总字节数(存在大量基本计数器的实现 - 请参阅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