Как переместить Primefaces-Upload-Temp-Files вместо выполнения трудоемкого процесса копирования?
Я хочу загрузить файлы размером более 2 ГБ с Java EE с использованием примитивов. В общем, это не так уж и важно, но у меня есть небольшая проблема. Обычно с помощью PrimeFaces можно загрузить файл, иметь этот UploadedFile-объект, получить из него входной поток и затем записать его на диск.
Но запись на диск больших файлов-это трудоемкая задача. Вместо этого я хотел бы найти загруженный файл в файловой системе, а затем переместить его в папку, где я храню все файлы, потому что перемещение файлов не является пустой тратой времени.Итак, согласно этому вопросу здесь я придумал установить PrimeFaces-Tmp-folder и ограничение по размеру, когда файлы будут туда помещаться. Теперь каждый загруженный файл просто попадает прямо в эту папку. Дело в том, что теперь у меня есть файл на диске, в то время как пользователь загружает - и не создает его после этого.
Пока все идет хорошо. Я мог бы идентифицировать файл и просто переместить его (Хотя у него странное имя). Но указывая на примитивы Userguide (страница 187) , Эта папка Tmp просто используется внутри. И я бы даже украл содержимое UploadedFile-объекта из Primefaces. Кажется, это не самое чистое решение для меня.
Какие-нибудь подсказки, как этого добиться ?
Я также видел этот вопрос. Может быть, это и мой титул, но это не то, что я ищу.
Правка:
Из-за комментария, какой-то код. Сначала я собираю UploadFile-объекты в fileUploadListener:
public void handleFileUpload(FileUploadEvent event) throws IOException {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
getUploadedFilesDTO().add(new UploadedFileDTO(event.getFile(), uploadedFilesCounter));
uploadedFilesCounter++;
}
{[2-секундный в EJB я вызываю copyFile для каждого UploadedFile-Объекта:
private void copyFile(UploadedFile uploadedFile, String randomFilename) throws IOException {
InputStream originalFile = uploadedFile.getInputstream();
OutputStream fileOutput = null;
try {
fileOutput = new FileOutputStream("/pvtfiles/" + randomFilename);
IOUtils.copy(originalFile, fileOutput);
} finally {
IOUtils.closeQuietly(fileOutput);
IOUtils.closeQuietly(originalFile);
}
}
2 ответа:
Создавая свой собственный фильтр, он не будет создавать временные файлы. Пожалуйста, прочтите мой ответ ниже на другом посте
Я смог сделать это, написав пользовательский фильтр, как предложил AZ_, и добавив следующее:
Фокус в том, чтобы использовать объектFileItem fileItem = multipartRequest.getFileItem("form:fileUpload"); File file = new File(uploadDir + "/" + fileItem.getName()); fileItem.write(file);
MultipartRequest
для получения объекта aFileItem
.FileItem
s Методwrite
может быть использован для сохранения файла в другом месте или с другим именем. Согласно документации, некоторые реализации все еще могут делать это с копией, но то, что я использую (Apache Commons 1.3), похоже, делает это с переименованием/перемещением по желанию. Обратите внимание, что строка, используемая вgetFileItem
, чтобы найтиFileItem
- это атрибут ID из тега<p:fileUpload>
.Еще Код:
Модифицированная часть
web.xml
:<filter> <filter-name>PrimeFaces FileUpload Filter</filter-name> <filter-class>some.package.CustomFileUploadFilter</filter-class> </filter>
Пример jsf:
<h:form id="form"> <h:panelGrid columns="1" class="blockleft"> <p:fileUpload id="fileUpload" auto="true" /> </h:panelGrid> </h:form>
Пример пользовательского класса фильтров:
package some.package; import java.io.File; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.primefaces.webapp.MultipartRequest; import org.primefaces.webapp.filter.FileUploadFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CustomFileUploadFilter extends FileUploadFilter { private static final Logger LOG = LoggerFactory.getLogger(CustomFileUploadFilter.class); private String thresholdSize; private String uploadDir; private final static String THRESHOLD_SIZE_PARAM = "thresholdSize"; private final static String UPLOAD_DIRECTORY_PARAM = "uploadDirectory"; @Override public void init(FilterConfig filterConfig) throws ServletException { thresholdSize = filterConfig.getInitParameter(THRESHOLD_SIZE_PARAM); uploadDir = filterConfig.getInitParameter(UPLOAD_DIRECTORY_PARAM); LOG.info("CatalogFileUploadFilter initiated successfully"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; boolean isMultipart = ServletFileUpload.isMultipartContent(httpServletRequest); if (isMultipart) { LOG.info("Parsing file upload request"); DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); if (thresholdSize != null){ diskFileItemFactory.setSizeThreshold(Integer.valueOf(thresholdSize).intValue()); } if (uploadDir != null){ diskFileItemFactory.setRepository(new File(uploadDir)); } ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory); MultipartRequest multipartRequest = new MultipartRequest(httpServletRequest, servletFileUpload); try { FileItem fileItem = multipartRequest.getFileItem("form:fileUpload"); File file = new File("path/to/location/" + fileItem.getName()); fileItem.write(file); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } LOG.info("File upload request parsed successfully, continuing with filter chain with a wrapped multipart request"); filterChain.doFilter(multipartRequest, response); } else { filterChain.doFilter(request, response); } } }