Как установить максимальный размер файла на основе имени файла, используя утилиты загрузки файлов Apache - PullRequest
1 голос
/ 10 июня 2011

У меня есть требование, когда мне нужно разрешить разные максимальные размеры файлов для разных случаев.Пример: разрешить 5 МБ для возобновления, только 3 МБ для расшифровок.

Я использую следующий код для загрузки файла с помощью утилит загрузки файлов 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);                
            }             
        }                

Единственный способ, которым я могунайдите имя поля с помощью item.getFieldName (), и я могу сделать это только после выполнения upload.getItemIterator, но setSizeMax (500 ..) должен быть установлен при загрузке до вызова upload.getItemIterator.

Есть ли способ обойти эту проблему?Если решения не существует, можете ли вы предложить какой-либо другой API для загрузки файлов, который решает эту проблему.

Спасибо

Ответы [ 2 ]

2 голосов
/ 24 февраля 2014

Если вместо этого вы циклически перебираете объект 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;
}

Конечно, вам придется добавить больше логикиесли существует более двух типов файлов, но вы можете видеть, что очень просто сравнить размеры файлов перед записью.

0 голосов
/ 10 июня 2011

Предполагая, что количество переменных неформального типа ограничено (и вы могли бы применить это), просто используйте итератор и используйте обтекание потока, чтобы вызвать исключение, когда общее количество байтов (существует множество реализаций базовых счетчиков - см. например, 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
...