Wicket FileUploadField и большие загрузки zip - PullRequest
1 голос
/ 13 декабря 2011

Я использую wicket для отправки больших (~ 2Gb +) zip-файлов в веб-приложение, для обработки zip-файла. Я использую классы java.util.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 () копирует его в другой временный файл, поэтому теперь у меня естьдве копии файла на диске.Это тратит впустую дисковое пространство, дисковый ввод-вывод и увеличивает время обработки запроса.

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

Ответы [ 2 ]

2 голосов
/ 14 декабря 2011

Опираясь на ответ @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;
    }

}
1 голос
/ 13 декабря 2011

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

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

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

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