问题
I'm getting Stream is closed Exception
when I'm going to save the uploaded image.
I'm tring to preview graphicImage
of uploaded image the before save. This operation is working. But I can't save the image. Here is my code:
private InputStream in;
private StreamedContent filePreview;
// getters and setters
public void upload(FileUploadEvent event)throws IOException {
// Folder Creation for upload and Download
File folderForUpload = new File(destination);//for Windows
folderForUpload.mkdir();
file = new File(event.getFile().getFileName());
in = event.getFile().getInputstream();
filePreview = new DefaultStreamedContent(in,"image/jpeg");
FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void setFilePreview(StreamedContent fileDownload) {
this.filePreview = fileDownload;
}
public StreamedContent getFilePreview() {
return filePreview;
}
public void saveCompanyController()throws IOException{
OutputStream out = new FileOutputStream(getFile());
byte buf[] = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
FileMasterDO fileMasterDO=new FileMasterDO();
fileMasterDO.setFileName(getFile().getName());
fileMasterDO.setFilePath(destination +file.getName());
fileMasterDO.setUserMasterDO(userMasterService.findUserId(UserBean.getUserId()));
fileMasterDO.setUpdateTimeStamp(new Date());
in.close();
out.flush();
out.close();
fileMasterService.save(filemaster);
}
The bean is in the session scope.
回答1:
You're trying to read an InputStream
twice (the first time is in DefaultStreamedContent
constructor of upload method and the second time is in the copy loop of the save method). This is not possible. It can be read only once. You need to read it into a byte[]
first and then assign it as a bean property so that you can reuse it for both the StreamedContent
and the save.
Make sure that you never hold external resources such as InputStream
or OutputStream
as a bean property. Remove them all from the current and other beans where applicable and use byte[]
to hold the image's content as property.
In your particular case, you need to fix it as follows:
private byte[] bytes; // No getter+setter!
private StreamedContent filePreview; // Getter only.
public void upload(FileUploadEvent event) throws IOException {
InputStream input = event.getFile().getInputStream();
try {
IOUtils.read(input, bytes);
} finally {
IOUtils.closeQuietly(input);
}
filePreview = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/jpeg");
// ...
}
public void saveCompanyController() throws IOException {
OutputStream output = new FileOutputStream(getFile());
try {
IOUtils.write(bytes, output);
} finally {
IOUtils.closeQuietly(output);
}
// ...
}
Note: IOUtils
is from Apache Commons IO, which you should already have in the classpath as it's a dependency of <p:fileUpload>
.
来源:https://stackoverflow.com/questions/13704387/stream-closed-exception