2011-12-13 2 views
1

Я использую калитки, чтобы иметь большие (~ 2Gb +) zip-файлы, отправленные в веб-приложение, для обработки zip-файла. Я использую классы java.util.zip. *, И мне нужно чтобы читать случайные записи из zip-файла. Так что мой код что-то вроде этого:Wicket FileUploadField и большие загрузки zip

class MyForm extends Form { 
    private FileUploadField fileField; 

    MyForm(String id) { 
     super(id); 
     fileField = new FileUploadField("upload"); 
     add(fileField); 
    } 

    @Override 
    protected void onSubmit() { 
     FileUpload fileUpload = fileField.getFileUpload(); 
     File file = fileUpload.writeToTempFile(); 
     ZipFile zipFile = new ZipFile(file); 
     // Do more stuff 
    } 
} 

Как загрузки большая калитка помещает его в временный файл при обработке запроса, но затем writeToTempFile() копирует его в другой временный файл, так что теперь у меня есть две копии файла на диске. Это отнимает дисковое пространство, диск IO и увеличивает время обработки запроса.

Я не могу использовать ZipFileInputStream, поскольку мне нужно получить доступ к файлам в случайном порядке. Есть ли способ остановить калитку, дублирующую файл на диске?

ответ

1

Да, но это нехороший способ.

Вы можете подкласса FileUploadField и переопределить метод getFileUpload() с копией, которая раскрывает базовые FileItem.

Или, другой путь, чтобы создать новый метод в FileUploadField подкласса просто вернуть FileItem:

public FileItem getFileItem() { 
    return ((IMultipartWebRequest)getRequest()).getFile(getInputName()); 
} 
+0

Спасибо , Чтобы завершить это, FileItem по-прежнему не дает вам доступа к файлу, DiskFileItem, который реализует FileItem, имеет метод getStoreLocation(), который делает, поэтому тест и литье. –

2

Опираясь на ответ от @biziclop Я написал этот класс:

public class RawFileUploadField extends FileUploadField { 

private static final long serialVersionUID = 1L; 

public RawFileUploadField(String id) { 
    super(id); 
} 

/** 
* Attempts to get the file that is on disk if it exists and if it doesn't 
* then just write the file to a temp location. 
* @return The file or <code>null</code> if no file. 
* @throws IOException 
*/ 
public File getFile() throws IOException { 
    // Get request 
    final Request request = getRequest(); 

    // If we successfully installed a multipart request 
    if (request instanceof IMultipartWebRequest) 
    { 
     // Get the item for the path 
     FileItem item = ((IMultipartWebRequest)request).getFile(getInputName()); 
     if (item instanceof DiskFileItem) { 
      File location = ((DiskFileItem)item).getStoreLocation(); 
      if (location != null) { 
       return location; 
      } 
     } 
    } 
    // Fallback 
    FileUpload upload = getFileUpload(); 
    return (upload != null)?upload.writeToTempFile():null; 
    } 

}