Wicket FileUploadField和大型zip上传

时间:2011-12-13 17:54:25

标签: java zip wicket

我正在使用wicket将大型(~2Gb +)zip文件提交给Web应用程序,处理我正在使用java.util.zip。*类的zip文件,我需要能够随机读取来自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
    }
}

由于上传很大,wicket在解析请求时会将其放入临时文件中,但是writeToTempFile()会将其复制到另一个临时文件中,所以我现在在磁盘上有两个文件副本。这会浪费磁盘空间,磁盘IO并增加请求处理时间。

我无法使用ZipFileInputStream,因为我需要以随机顺序访问文件。有没有办法阻止wicket复制磁盘上的文件?

2 个答案:

答案 0 :(得分: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;
    }

}

答案 1 :(得分:1)

是的,但这不是一个好方法。

您可以创建FileUploadField的子类,并使用公开基础getFileUpload()的副本覆盖FileItem方法。

或者,另一种方法是在FileUploadField子类中创建一个新方法,只是为了返回FileItem

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